1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SMESH_Block.hxx
21 // Created : Tue Nov 30 12:42:18 2004
22 // Author : Edward AGAPOV (eap)
25 #ifndef SMESH_Block_HeaderFile
26 #define SMESH_Block_HeaderFile
29 #include <TopTools_IndexedMapOfOrientedShape.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Shell.hxx>
33 #include <TopoDS_Vertex.hxx>
42 class SMDS_MeshVolume;
44 class Adaptor3d_Surface;
45 class Adaptor2d_Curve2d;
46 class Adaptor3d_Curve;
48 // =========================================================
49 // class calculating coordinates of 3D points by normalized
50 // parameters inside the block and vice versa
51 // =========================================================
57 // ----------------------------
58 // Ids of the block sub-shapes
59 // ----------------------------
62 ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
64 ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
65 ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
66 ID_E00z, ID_E10z, ID_E01z, ID_E11z,
68 ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
72 enum { // to use TShapeID for indexing certain type subshapes
74 ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0
80 // -------------------------------------------------
81 // Block topology in terms of block sub-shapes' ids
82 // -------------------------------------------------
84 static int NbVertices() { return 8; }
85 static int NbEdges() { return 12; }
86 static int NbFaces() { return 6; }
87 static int NbSubShapes() { return ID_Shell; }
88 // to avoid magic numbers when allocating memory for subshapes
90 static inline bool IsVertexID( int theShapeID )
91 { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
93 static inline bool IsEdgeID( int theShapeID )
94 { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
96 static inline bool IsFaceID( int theShapeID )
97 { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
99 static int ShapeIndex( int theShapeID )
101 if ( IsVertexID( theShapeID )) return theShapeID - ID_V000;
102 if ( IsEdgeID( theShapeID )) return theShapeID - ID_Ex00;
103 if ( IsFaceID( theShapeID )) return theShapeID - ID_Fxy0;
106 // return index [0-...] for each type of sub-shapes,
108 // ShapeIndex( ID_Ex00 ) == 0
109 // ShapeIndex( ID_Ex10 ) == 1
111 static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec );
112 // return edges IDs of a face in the order u0, u1, 0v, 1v
114 static void GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec );
115 // return vertex IDs of an edge
117 static int GetCoordIndOnEdge (const int theEdgeID)
118 { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
119 // return an index of a coordinate which varies along the edge
121 static double* GetShapeCoef (const int theShapeID);
122 // for theShapeID( TShapeID ), returns 3 coefficients used
123 // to compute an addition of an on-theShape point to coordinates
124 // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
125 // then the addition of a point P is computed as P*kx*ky*kz and ki is
126 // defined by the returned coef like this:
127 // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
129 static int GetShapeIDByParams ( const gp_XYZ& theParams );
130 // define an id of the block sub-shape by point parameters
132 static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream);
133 // DEBUG: dump an id of a block sub-shape
143 bool LoadBlockShapes(const TopoDS_Shell& theShell,
144 const TopoDS_Vertex& theVertex000,
145 const TopoDS_Vertex& theVertex001,
146 TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
147 // Initialize block geometry with theShell,
148 // add sub-shapes of theBlock to theShapeIDMap so that they get
149 // IDs acoording to enum TShapeID
151 bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
152 // Initialize block geometry with shapes from theShapeIDMap
154 bool LoadMeshBlock(const SMDS_MeshVolume* theVolume,
155 const int theNode000Index,
156 const int theNode001Index,
157 vector<const SMDS_MeshNode*>& theOrderedNodes);
158 // prepare to work with theVolume and
159 // return nodes in theVolume corners in the order of TShapeID enum
161 bool LoadFace(const TopoDS_Face& theFace,
163 const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
164 // Load face geometry.
165 // It is enough to compute params or coordinates on the face.
166 // Face subshapes must be loaded into theShapeIDMap before
168 static bool Insert(const TopoDS_Shape& theShape,
169 const int theShapeID,
170 TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
171 // Insert theShape into theShapeIDMap with theShapeID,
172 // Not yet set shapes preceding theShapeID are filled with compounds
173 // Return true if theShape was successfully bound to theShapeID
175 static bool FindBlockShapes(const TopoDS_Shell& theShell,
176 const TopoDS_Vertex& theVertex000,
177 const TopoDS_Vertex& theVertex001,
178 TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
179 // add sub-shapes of theBlock to theShapeIDMap so that they get
180 // IDs acoording to enum TShapeID
183 // ---------------------------------
184 // Define coordinates by parameters
185 // ---------------------------------
187 bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
188 if ( !IsVertexID( theVertexID )) return false;
189 thePoint = myPnt[ theVertexID - ID_FirstV ]; return true;
191 // return vertex coordinates, parameters are defined by theVertexID
193 bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
194 if ( !IsEdgeID( theEdgeID )) return false;
195 thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true;
197 // return coordinates of a point on edge
199 bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const {
200 if ( !IsEdgeID( theEdgeID )) return false;
201 theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true;
203 // return parameter on edge by in-block parameters
205 bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
206 if ( !IsFaceID ( theFaceID )) return false;
207 thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true;
209 // return coordinates of a point on face
211 bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const {
212 if ( !IsFaceID ( theFaceID )) return false;
213 theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true;
215 // return UV coordinates on a face by in-block parameters
217 bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
218 // return coordinates of a point in shell
220 static bool ShellPoint(const gp_XYZ& theParams,
221 const vector<gp_XYZ>& thePointOnShape,
223 // computes coordinates of a point in shell by points on sub-shapes
224 // and point parameters.
225 // thePointOnShape[ subShapeID ] must be a point on a subShape;
226 // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used
230 // ---------------------------------
231 // Define parameters by coordinates
232 // ---------------------------------
234 bool ComputeParameters (const gp_Pnt& thePoint,
236 const int theShapeID = ID_Shell,
237 const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1));
238 // compute point parameters in the block.
239 // Note: for edges, it is better to use EdgeParameters()
241 bool VertexParameters(const int theVertexID, gp_XYZ& theParams);
242 // return parameters of a vertex given by TShapeID
244 bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams);
245 // return parameters of a point given by theU on edge
260 static bool IsForwardEdge (const TopoDS_Edge & theEdge,
261 const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
262 int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
263 int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
264 return ( v1ID < v2ID );
266 // Return true if an in-block parameter increases along theEdge curve
268 static int GetOrderedEdges (const TopoDS_Face& theFace,
269 TopoDS_Vertex theFirstVertex,
270 std::list< TopoDS_Edge >& theEdges,
271 std::list< int > & theNbVertexInWires);
272 // Return nb wires and a list of oredered edges.
273 // It is used to assign indices to subshapes.
274 // theFirstVertex may be NULL.
275 // Always try to set a seam edge first
281 * \brief Call it after geometry initialisation
285 // Note: to compute params of a point on a face, it is enough to set
286 // TFace, TEdge's and points for that face only
288 // Note 2: curve adaptors need to have only Value(double), FirstParameter() and
289 // LastParameter() defined to be used by Block algoritms
295 Adaptor3d_Curve* myC3d;
299 void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward );
300 void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 );
301 Adaptor3d_Curve* GetCurve() const { return myC3d; }
302 double EndParam(int i) const { return i ? myLast : myFirst; }
303 int CoordInd() const { return myCoordInd; }
304 const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; }
305 gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params
306 double GetU( const gp_XYZ& theParams ) const; // Return U by params
312 // 4 edges in the order u0, u1, 0v, 1v
314 double myFirst [ 4 ];
316 Adaptor2d_Curve2d* myC2d [ 4 ];
317 // 4 corner points in the order 00, 10, 11, 01
318 gp_XY myCorner [ 4 ];
320 Adaptor3d_Surface* myS;
324 void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order:
325 Adaptor2d_Curve2d* c2d[4], const bool isForward[4] );
326 void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 );
327 gp_XY GetUV( const gp_XYZ& theParams ) const;
328 gp_XYZ Point( const gp_XYZ& theParams ) const;
329 int GetUInd() const { return myCoordInd[ 0 ]; }
330 int GetVInd() const { return myCoordInd[ 2 ]; }
331 void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const;
332 TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; }
336 // geometry in the order as in TShapeID:
344 // for param computation
347 double mySumDist, myTolerance;
349 typedef pair<gp_XYZ,gp_XYZ> TxyzPair;
350 TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess