cgma
RefFace.hpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Copyright Notice
00003 //
00004 // Copyright (c) 1996 
00005 // by Malcolm J. Panthaki, DBA, and the University of New Mexico.
00006 //-------------------------------------------------------------------------
00007 
00008 //-------------------------------------------------------------------------
00009 //
00010 // Filename      : RefFace.hpp
00011 //
00012 // Purpose       : A RefFace is a BasicTopologyEntity.  It is a topological
00013 //                 entity that represents a bounded surface.  A RefFace is a
00014 //                 contiguous point set, but can have multiple "holes"
00015 //                 within it. It is a topologically 2-D entity.
00016 //
00017 //                 A RefFace can be meshed.                
00018 //
00019 // Special Notes : 
00020 //
00021 // Creator       : Malcolm J. Panthaki
00022 //
00023 // Creation Date : 07/11/96
00024 //
00025 // Owner         : Malcolm J. Panthaki
00026 //-------------------------------------------------------------------------
00027 
00028 #ifndef REFFACE_HPP
00029 #define REFFACE_HPP
00030 
00031 // ********** BEGIN STANDARD INCLUDES      **********
00032 // ********** END STANDARD INCLUDES        **********
00033 
00034 // ********** BEGIN MOTIF INCLUDES         **********
00035 // ********** END MOTIF INCLUDES           **********
00036 
00037 // ********** BEGIN OPEN INVENTOR INCLUDES **********
00038 // ********** END OPEN INVENTOR INCLUDES   **********
00039 
00040 // ********** BEGIN CUBIT INCLUDES         **********
00041 #include "CastTo.hpp"
00042 #include "BasicTopologyEntity.hpp"
00043 #include "LocalStart.h"
00044 
00045 
00046 // ********** END CUBIT INCLUDES           **********
00047 
00048 // ********** BEGIN MACROS DEFINITIONS     **********
00049 // ********** END MACROS DEFINITIONS       **********
00050 
00051 // ********** BEGIN TYPEDEF DEFINITIONS    **********
00052 // ********** END TYPEDEF DEFINITIONS      **********
00053 
00054 // ********** BEGIN ENUM DECLARATIONS      **********
00055 // ********** END ENUM DECLARATIONS        **********
00056 
00057 // ********** BEGIN FORWARD DECLARATIONS   **********
00058 
00059 
00060 class CoEdge;
00061 template <class X> class DLIList;
00062 class RefVertex;
00063 class CoFace;
00064 class Loop;
00065 class CoFace;
00066 class SurfMeshTool;
00067 class SurfVertexType;
00068 class TDUVSpace;
00069 class Surface;
00070 class GMem;
00071 
00072 // ********** END FORWARD DECLARATIONS     **********
00073 
00074 class CUBIT_GEOM_EXPORT RefFace : public BasicTopologyEntity
00075 {
00076 public :
00077   
00078   typedef RefEdge ChildType;
00079   typedef RefVolume ParentType;
00080   
00081   friend class RefEntityFactory;
00082     //- the factory is allowed to call the (private) constructors
00083 
00084     /* constructors/destructors */
00085 
00086   virtual ~RefFace() ;
00087     //- The destructor
00088 
00089   static const char* get_class_name()
00090      {
00091        return "Surface";
00092      }
00093 
00094   virtual const char* class_name() const
00095      {
00096        return get_class_name();
00097      }
00098   
00099     /* topology */
00100   DagType dag_type() const { return DagType::ref_face_type(); }
00101   const std::type_info& entity_type_info() const { return typeid(RefFace); }
00102 
00103   void get_parent_ref_entities(DLIList<RefEntity*>& entity_list);
00104 
00105   CubitStatus get_co_faces( DLIList<CoFace*> &co_faces_found_list,
00106                             RefVolume *input_ref_volume_ptr );
00107     //R CubitStatus
00108     //R- CubitSuccess/CubitFailure
00109     //O co_faces_found_list
00110     //O-Populates the co_faces_found_list with the CoFaces that are
00111     //-associated with this RefFace.  Because the input RefVolume is sent
00112     //-in it fills the list just with the CoFaces that are associated with
00113     //-this RefVolume.  Note that usually there will be only one CoFace with
00114     //-the RefVolume but with HardSurfaces there may be more (2).
00115 
00116   CubitStatus ordered_loops( DLIList<Loop*> &loop_list );
00117     //- Gets the loops in order from outside to inside.
00118     //- This function is used for all the loop extracting from the refface,
00119     //- i.e., nodes, ref-edges, ref-vertices.  This function orders the
00120     //- loops based on the angle metric calculation.  I believe this metric
00121     //- is actually currently calculated in OCCGeometryEngine but I see
00122     //- no reason that it should be done there.  I believe it could be
00123     //- done in the Loop class.
00124 
00125   int co_edge_loops ( DLIList<DLIList<CoEdge*> >& co_edge_loops );
00126     //- Returns a list of lists.  Each of the included lists contains a list
00127     //- of CoEdges and represents an ordered list of CoEdges associated
00128     //- with each of the Loops of this RefFace.
00129   
00130   int ref_edge_loops ( DLIList<DLIList<RefEdge*> >& ref_edge_loops );
00131     //- Returns a list of lists.  Each of the included lists contains a list
00132     //- of RefEdges and represents an ordered list of RefEdges associated
00133     //- with each of the Loops of this RefFace.
00134     //- NOTE: All of the ref_edge_lists in ref_edge_loops will 
00135     //-       need to be deleted by the *calling* function.  
00136   
00137   void ref_vertex_loops( DLIList<DLIList<RefVertex*> >& ref_vert_loop_list );
00138     //- Returns a list of lists.  Each of the included lists contains a list
00139     //- of RefVertex'es and represents an ordered list of RefVertex'es 
00140     //- associated with each of the Loops of this RefFace.  
00141     //- NOTE: All of the ref_vertex_lists in the ref_vert_loop_list will 
00142     //-       need to be deleted by the *calling* function.
00143   
00144   int  number_of_Loops ();
00145     //- Returns the number of Loops associated with this RefFace
00146   
00147   
00148   RefVolume* ref_volume();
00149     //- Return the first RefVolume pointer to the volume which owns
00150     //- this RefFace
00151     //- Note: There may be more than one RefVolume that owns this RefFace.
00152     //-       This method just gets the first in the list.
00153 
00154   void hard_points( DLIList<RefVertex*>& new_hard_point_list );
00155     //- Populate the input DLIList<RefVertex*> with the list of hard points 
00156     //- that are defined for this RefFace
00157   
00158   int adjoins ( RefFace* input_face_ptr );
00159     //- Returns CUBIT_TRUE if this RefFace adjoins (is connected via a RefEdge)
00160     //- the input RefFace
00161   
00162   RefVolume* common_ref_volume ( RefFace* input_face_ptr );
00163     //- Returns a common RefVolume* if this RefFace shares one with the
00164     //- input RefFace
00165 
00166   RefEdge* common_ref_edge ( RefFace* input_face_ptr );
00167     //- Returns a common RefEdge* if this RefFace shares one with the
00168     //- input RefFace
00169 
00170   int common_ref_edges ( RefFace* input_face_ptr, DLIList<RefEdge*> &common_edge_list );
00171     //- Returns all common RefEdges that this face shares with the input face
00172 
00173   CoFace* get_matching_CoFace(RefVolume* ref_volume_ptr) ;
00174     //R CoFace*
00175     //R- Returned CoFace pointer
00176     //I ref_volume_ptr
00177     //I- The RefVolume to which matching is done.
00178     //- This function returns the CoFace that is associated with both "this"
00179     //- RefFace as well as with the input RefVolume.  The function is useful
00180     //- when a merge operation has resulted in a RefFace that is shared by
00181     //- more than 1 RefVolume (most often, two). In this case, the RefFace
00182     //- would be associated with more than one CoFace, each belonging to a 
00183     //- different RefVolume.
00184     //- If there is no match (i.e., this RefFace is not associated with the
00185     //- input RefVolume) then a NULL pointer is returned.
00186 
00187   int genus();
00188     //- return genus of this surfaces, which is defined as
00189     //- g = (L ? L-1 : -(P+1)) where L = # loops, P = # poles
00190   
00191   int num_poles();
00192     //- return the number of singular poles on this surface
00193   
00194     /*  geometry */
00195 
00196   virtual CubitVector center_point();
00197     //- Return the approximate (spatial) center of this RefFace
00198   
00199   CubitSense sense(RefVolume* volume);
00200     //-Determines the sense of "this" with respect to the passed-in volume.
00201         
00202     CubitSense sense(RefFace* face_ptr);
00203         //-Determine the relative sense of the passed face with respect to
00204         //-this face using the senses of common RefEdges.  i.e. if 
00205         //-CUBIT_REVERSED is returned, than the sense of the passed face
00206         //-should be the opposite of that of this face with respect to
00207         //-any volume.  CUBIT_UNKNOWN is returned if there are no
00208         //-common RefEdges between RefFaces or there is more than one
00209         //-common RefEdge.
00210 
00211   CubitSense get_geometry_sense();
00212     //- Gets the sense of the reface with respect to the underlying
00213     //- geometry engines representation of the surface.
00214 
00215   CubitBoolean about_spatially_equal ( RefFace* ref_face_ptr_2,
00216                                        double tolerance_factor = 1.0,
00217                                        CubitBoolean notify_refEntity =
00218                                        CUBIT_FALSE,
00219                                        CubitBoolean test_bbox = CUBIT_TRUE,
00220                                        int test_internal = 0 );
00221   
00222     //R CubitBoolean
00223     //R-CUBIT_TRUE/CUBIT_FALSE
00224     //I RefFace*, double, CubitBoolean
00225     //I- Second RefFace to compare, Tolerance factor to for GEOMETRY_RESABS,
00226     //I- and flag for notifying compared RefEntities.
00227     //O CubitBoolean
00228     //O- If the two RefFaces are spatially equal within the GEOMETRY_RESABS*
00229     //- the tolerance_factor, then CUBIT_TRUE will be returned.  Otherwise
00230     //- CUBIT_FALSE is returned.
00231     //- The comparison is done by first checking the bounding boxes of the
00232     //- RefFaces.  If this test is passed then the ref_edges of each face
00233     //- are looped through and compared.  A bounding box check for each
00234     //- edge is also done first before a comparison, for speed.
00235   
00236   CubitSense compare_alignment( RefFace* second_ref_face_ptr );
00237     //R CubitSense
00238     //R- Sense of this reface with respect to the second one passed in.
00239     //I RefFace *
00240     //I- pointer to second ref face with which the alignment is compared.
00241     //- This function will compare the sense of the two ref-faces, or
00242     //- rather their normals.
00243     //- NOTE: It is ASSUMED that BOTH reffaces are SPATIALLY EQUAL.
00244     //- If this is not followed this could explode.
00245   
00246 
00247   CubitVector normal_at(const CubitVector& location, RefVolume* volume=NULL, double* u_guess = NULL, double* v_guess = NULL);
00248     //- Calculate normal for input location (optional input RefVolume to 
00249     //- allow for feature consolidation). 
00250     //- Note that the input location is modified to the coordinates
00251     //- of the closest point on the surface.
00252     //-
00253     //- MJP NOTE:
00254     //- In the previous implementation, the result of this function call 
00255     //- would not only be the returned unit vector which is the normal
00256     //- at the location, but the function would also fill in the myPosition
00257     //- and myParametricPosition data members of RefFace.  These data
00258     //- members have been removed in this implementation of RefFace.
00259     //- However, the Surface::normal_at function that gets called returns
00260     //- an additional parameter which is the location on the underlying
00261     //- surface that is closest to the input location.
00262   void reverse_normal();
00263     //- switch the sense of this face with respect to the underlying
00264     //- geometry, so that all normals point in the opposite
00265     //- direction. The orientation of quads on the surface are switched
00266     //- to agree with this normal.
00267   virtual void reverse_topology();
00268 
00269 //========  Change Code by DZ of Cat,  on 10/29/98 8:46:59 AM  ========
00270   CubitBoolean set_outward_normal( RefVolume *volume );
00271     //- Set the normal of this face to point outward wrt to given volume.
00272     //- Assumes there is only one coface of the volume for this RefFace.
00273     //- Uses the above "reverse_normal" function.
00274     //- return true only if reverse_normal function called.
00275 //========  Change End by DZ of Cat,  on 10/29/98 8:46:59 AM  ========
00276 
00277   virtual void move_to_surface ( CubitVector& location, double* u_guess = NULL, double* v_guess = NULL);
00278     //- Moves the given node back onto its surface
00279 
00280   virtual CubitStatus move_to_surface( CubitVector& location, CubitVector& along_vec );
00281   //- Moves the given location onto surface along the specified direction
00282   
00283   void find_closest_point_trimmed(CubitVector from_point, 
00284                                   CubitVector& point_on_surface);
00285     //R void
00286     //I CubitVector
00287     //I- point from which to find closest point on trimmed surface
00288     //O CubitVector
00289     //O- point on trimmed surface closest to passed-in point 
00290     //- This function finds the closest point on a TRIMMED surface to the
00291     //- passed-in point.  
00292 
00293   void find_closest_points_trimmed(std::vector<CubitVector> &from_points, 
00294                                    std::vector<CubitVector> &points_on_surface );
00295 
00296   CubitPointContainment point_containment( const CubitVector &point );
00297   CubitPointContainment point_containment( double u, double v );
00298 //  CubitPointContainment point_containment( CubitVector &point, double u, double v );
00299     //R CubitPointContainment - is the point outside, inside or on the boundary?
00300     //R- CUBIT_PNT_OUTSIDE, CUBIT_PNT_INSIDE, CUBIT_PNT_BOUNDARY, 
00301     //   CUBIT_PNT_UNKNOWN
00302     //I CubitVector
00303     //I- position to check, known to be on the Surface
00304     //I double
00305     //I- u coordinate, if known (significantly faster, if this is known - however
00306     //                           if not known let the function figure it out)
00307     //I double
00308     //I- v coordinate, if known (significantly faster, if this is known - however
00309     //                           if not known let the function figure it out)
00310     // NOTE: POINT MUST LIE ON THE SURFACE FOR THIS FUNCTION TO WORK PROPERLY.
00311   
00312   CubitStatus get_principal_curvatures( const CubitVector& point,
00313                                         double& curvature1,
00314                                         double& curvature2,
00315                                         RefVolume* ref_volume_ptr = NULL );
00316     //R CubitStatus 
00317     //R- CUBIT_SUCCESS/FAILURE
00318     //I point
00319     //I- Input location. The coordinates of this input point are 
00320     //I- modified to those of the point closest to this one, on the
00321     //I- surface of this RefFace.
00322     //O curvature1/curvature2
00323     //O- Output principal curvature values.
00324     //I ref_volume_ptr
00325     //I- Input RefVolume pointer
00326     //- This function first computes the point on the surface closest to the
00327     //- input point and sets the values of "point" to this closest
00328     //- location.  Then, the principal curvatures of the surface at this 
00329     //- new point are computed and returned. If the input RefVolume pointer
00330     //- is not NULL, it is used when computing the curvatures.
00331   
00332   //Given a u and v, evaluate position and/or normal and/or curvature
00333   CubitStatus evaluate( double u, double v,
00334                         CubitVector *position,
00335                         CubitVector *normal,
00336                         CubitVector *curvature1,
00337                         CubitVector *curvature2 );
00338 
00339   CubitVector position_from_u_v (double u, double v);
00340     //- Return a CubitVector (representing a position vector corresponding 
00341     //- to the input point in {u,v} space
00342   
00343   CubitStatus u_v_from_position (CubitVector const& location,
00344                                  double& u, 
00345                                  double& v,
00346                                  CubitVector* closest_location = NULL );
00347     //R CubitStatus 
00348     //R- CUBIT_SUCCESS/FAILURE
00349     //I location
00350     //I- The input point in global space
00351     //O u, v
00352     //O- The returned u, v coordinate values (in local parametric space)
00353     //O- of the closest_point
00354     //O closest_location
00355     //O- The point on the Surface closest to the input location
00356     //I refvolume_ptr
00357     //I- The reference RefVolume with respect to which, the normal
00358     //I- is to be computed.  If the pointer is NULL, then the 
00359     //I- first underlying solid model entity is used to compute the
00360     //I- normal.
00361     //- This function returns the {u, v} coordinates of the point 
00362     //- on the Surface closest to the input point (specified in global
00363     //- space). The closest_location is also returned.
00364   
00365   CubitBoolean is_parametric();
00366     //R CubitBoolean
00367     //R- CUBIT_TRUE/CUBIT_FALSE
00368     //- This function determines whether the underlying geometry of the
00369     //- Surface is parametrically defined or not.  Returns CUBIT_TRUE if 
00370     //- it is and CUBIT_FALSE if it is not.
00371   
00372   CubitBoolean get_param_range_U( double& lower_bound,
00373                                   double& upper_bound );
00374     //R CubitBoolean
00375     //R- CUBIT_TRUE/CUBIT_FALSE
00376     //O lower_bound
00377     //O- The lower bound of the parametric range in the U direction.
00378     //O- This is set to 0.0 if the surface is not parametric.
00379     //O upper_bound
00380     //O- The upper bound of the parametric range in the U direction.
00381     //O- This is set to 0.0 if the surface is not parametric.
00382     //- Returns the lower and upper parametric bounds of the 
00383     //- surface in U, if it is parametric.  Otherwise, it returns
00384     //- CUBIT_FALSE and zeroes for the upper and lower parametric
00385     //- bounds.
00386   
00387   CubitBoolean get_param_range_V( double& lower_bound,
00388                                   double& upper_bound );
00389     //R CubitBoolean
00390     //R- CUBIT_TRUE/CUBIT_FALSE
00391     //O lower_bound
00392     //O- The lower bound of the parametric range in the V direction.
00393     //O- This is set to 0.0 if the surface is not parametric.
00394     //O upper_bound
00395     //O- The upper bound of the parametric range in the V direction.
00396     //O- This is set to 0.0 if the surface is not parametric.
00397     //- Returns the lower and upper parametric bounds of the 
00398     //- surface in V, if it is parametric.  Otherwise, it returns
00399     //- CUBIT_FALSE and zeroes for the upper and lower parametric
00400     //- bounds.
00401   
00402   CubitBoolean is_periodic();
00403     //R CubitBoolean
00404     //R- CUBIT_TRUE/CUBIT_FALSE
00405     //- This function determines whether the underlying geometry of the
00406     //- Surface is periodic or not.  Returns CUBIT_TRUE if it is and 
00407     //- CUBIT_FALSE if it is not.
00408   
00409   CubitBoolean is_periodic_in_U( double& period );
00410     //R CubitBoolean
00411     //R- CUBIT_TRUE/CUBIT_FALSE
00412     //O period
00413     //O- The value of the period in the U direction.
00414     //- Determines whether the surface object is 
00415     //- periodic in the U direction or not.  If it is, it
00416     //- returns CUBIT_TRUE and the value of the period. Otherwise,
00417     //- it returns CUBIT_FALSE and a value of 0.0 or the period.
00418   
00419   CubitBoolean is_periodic_in_V( double& period );
00420     //R CubitBoolean
00421     //R- CUBIT_TRUE/CUBIT_FALSE
00422     //O period
00423     //O- The value of the period in the V direction.
00424     //- Determines whether the surface object is 
00425     //- periodic in the V direction or not.  If it is, it
00426     //- returns CUBIT_TRUE and the value of the period. Otherwise,
00427     //- it returns CUBIT_FALSE and a value of 0.0 or the period.
00428 
00429   CubitBoolean is_singular_in_U( double u_param );
00430   CubitBoolean is_singular_in_V( double v_param );
00431     //R CubitBoolean
00432     //R- CUBIT_TRUE/CUBIT_FALSE
00433     //I double u/v parameter value.
00434     //- Determines if the surface is singular in a given direction
00435     //- at a given parameter value.
00436 
00437   CubitBoolean is_closed_in_U();  
00438   CubitBoolean is_closed_in_V();
00439     //R CubitBoolean
00440     //R- CUBIT_TRUE/CUBIT_FALSE
00441     //- Determines if the surface is closed, smoothly or not in the
00442     //- given parameter direction.
00443     //- A periodic surface is always closed but a closed surface is
00444     //- is not always periodic.
00445 
00446   CubitStatus uv_derivitives( double u_param,
00447                               double v_param,
00448                               CubitVector &du,
00449                               CubitVector &dv );
00450     //R CubitStatus
00451     //R- CUBIT_SUCCESS/CUBIT_FAILURE
00452     //O- du, dv
00453     //- Determines the u and v derivitives from the given parameter
00454     //- values.
00455 
00456   virtual int dimension() const; 
00457     //- Returns the geometric dimension of RefFace entities. 
00458 
00459   double area();
00460     //- get the area of the underlying surface
00461 
00462   virtual double measure();
00463   virtual CubitString measure_label();
00464   
00465   CubitBoolean is_planar();
00466     //R CubitBoolean
00467     //R CUBIT_TRUE/CUBIT_FALSE
00468     //- This function returns CUBIT_TRUE if the underlying geometry
00469     //- of the face is planar. CUBIT_FALSE otherwise.
00470   
00471   CubitBoolean is_cylindrical();
00472     //R CubitBoolean
00473     //R CUBIT_TRUE/CUBIT_FALSE
00474     //- This function returns CUBIT_TRUE if the underlying geometry
00475     //- of the face is conical (cylinders are subsets of cones). 
00476     //- CUBIT_FALSE otherwise.
00477 
00478   CubitStatus get_point_normal( CubitVector& origin, CubitVector& normal );
00479     //- Only valid for planar surfaces
00480     //- Finds the underlying plane's origin and normal (unit) vector
00481     //- Returns CUBIT_FAILURE if surface is not a plane
00482   
00483   virtual int validate();
00484     //- Check that entity is valid. Returns number of problems detected.
00485 
00486   double get_crack_length();
00487     //- return the length of the periodic crack, or 0.0 if non-periodic.
00488 
00489     /* geometry modification */
00490 
00491   void add_hard_point(  RefVertex* ref_vertex_ptr );
00492     //- Add a hard point to this RefFace. 
00493     //-***************************************************************
00494     //- MJP Note:
00495     //- Currently, the new RefVertex that is created is NOT PART OF THE
00496     //- main DAG datastructure. The new RefVertex, however, has its
00497     //- own little mini-DAG which consists of a single DAGNode.
00498     //- Discuss this with the team before making it a part of the main DAG. 
00499     //- It is, however, deleted appropriately when the RefFace is deleted.
00500     //-***************************************************************
00501 
00502     /* other functions */
00503 
00504   Surface* get_surface_ptr() ;
00505   Surface const* get_surface_ptr() const ;
00506     //R Surface*
00507     //R- A pointer to the Surface to which the current 
00508     //R- face points. 
00509     //- This function returns a pointer to the Surface
00510     //- to which the current face points.
00511   
00512   CubitStatus get_graphics( GMem& results, 
00513                             unsigned short normal_tolerance = 15,
00514                             double distance_tolerance = 0.0,
00515                             double longest_edge = 0.0 );
00516 
00517   CubitStatus get_projected_distance_on_surface( CubitVector *pos1,
00518                                                  CubitVector *pos2, 
00519                                                  double &distance );
00520 
00521 protected :
00522 
00523   RefFace(Surface* surfacePtr) ;
00524     //- The constructor with a pointer to a Surface.
00525   
00526   DLIList<RefVertex*> hardPointList;
00527 
00528 private:
00529 
00530   RefFace( const RefFace& );
00531   void operator=( const RefFace& );
00532   
00533   void initialize ();
00534     //- initialization method
00535   
00536   double maxPositionDeviation;
00537   
00538   int hardPointColor;
00539 
00540 };
00541 
00542 template <> struct DLIListSorter<RefFace*>
00543 {
00544   bool operator()(RefFace* a, RefFace* b) { return a->id() < b->id(); }
00545 };
00546 
00547 #endif
00548 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines