1 // Created on: 1999-11-02
2 // Created by: Peter KURNEV
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <Adaptor3d_CurveOnSurface.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepTools.hxx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Ellipse.hxx>
28 #include <Geom2d_Hyperbola.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Parabola.hxx>
31 #include <Geom2d_TrimmedCurve.hxx>
32 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <GeomAbs_CurveType.hxx>
37 #include <GeomAdaptor_Curve.hxx>
38 #include <GeomAdaptor_Surface.hxx>
39 #include <GeomAPI_ProjectPointOnCurve.hxx>
40 #include <GeomProjLib.hxx>
41 #include <gp_Dir.hxx>
42 #include <gp_Pnt.hxx>
43 #include <gp_Pnt2d.hxx>
44 #include <gp_Vec.hxx>
45 #include <Precision.hxx>
46 #include <ProjLib_ProjectedCurve.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TopExp.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <TopLoc_Location.hxx>
51 #include <TopoDS.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Wire.hxx>
56 #include <TopOpeBRepBuild_CorrectFace2d.hxx>
57 #include <TopOpeBRepBuild_Tools.hxx>
58 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
59 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
60 #include <TopOpeBRepDS_DataStructure.hxx>
61 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
62 #include <TopOpeBRepDS_ShapeWithState.hxx>
63 #include <TopOpeBRepTool_2d.hxx>
64 #include <TopOpeBRepTool_CurveTool.hxx>
65 #include <TopOpeBRepTool_ShapeClassifier.hxx>
66 #include <TopOpeBRepTool_TOOL.hxx>
67 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
68 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <TopTools_MapIteratorOfMapOfShape.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <TopTools_SequenceOfShape.hxx>
72 
73 #include <stdio.h>
74 //define parameter division number as 10*e^(-PI) = 0.43213918
75 const Standard_Real PAR_T = 0.43213918;
76 
77 //=======================================================================
78 //function TopOpeBRepBuild_Tools::FindState
79 //purpose  :
80 //=======================================================================
FindState(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopAbs_ShapeEnum aSubshEnum,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)81   void TopOpeBRepBuild_Tools::FindState (const TopoDS_Shape& aSubsh,
82 					 const TopAbs_State aState,
83 					 const TopAbs_ShapeEnum aSubshEnum,
84 					 const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
85 					 TopTools_MapOfShape& aMapProcessedSubsh,
86 					 TopOpeBRepDS_DataMapOfShapeState& aMapSS)
87 {
88   Standard_Integer i, nSub;
89   const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
90   TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
91   for (; anIt.More(); anIt.Next()) {
92     const TopoDS_Shape& aS=anIt.Value();
93     TopTools_IndexedMapOfShape aSubshMap;
94     TopExp::MapShapes (aS, aSubshEnum, aSubshMap);
95     nSub=aSubshMap.Extent();
96     for (i=1; i<=nSub; i++) {
97       const TopoDS_Shape& aSS=aSubshMap(i);
98       if (! aMapProcessedSubsh.Contains(aSS)) {
99 	aMapProcessedSubsh.Add(aSS);
100 	aMapSS.Bind (aSS, aState);
101 	FindState (aSS, aState, aSubshEnum, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
102       }
103     }
104   }
105 }
106 
107 //=======================================================================
108 //function TopOpeBRepBuild_Tools::PropagateState
109 //purpose  :
110 //=======================================================================
PropagateState(const TopOpeBRepDS_DataMapOfShapeState & aSplShapesState,const TopTools_IndexedMapOfShape & aShapesToRestMap,const TopAbs_ShapeEnum aSubshEnum,const TopAbs_ShapeEnum aShapeEnum,TopOpeBRepTool_ShapeClassifier & aShapeClassifier,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState,const TopTools_MapOfShape & anAvoidSubshMap)111   void TopOpeBRepBuild_Tools::PropagateState (const TopOpeBRepDS_DataMapOfShapeState& aSplShapesState,
112 					      const TopTools_IndexedMapOfShape& aShapesToRestMap,
113 					      const TopAbs_ShapeEnum aSubshEnum,// Vertex
114 					      const TopAbs_ShapeEnum aShapeEnum,//Edge
115 					      TopOpeBRepTool_ShapeClassifier& aShapeClassifier,
116 					      TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState,
117                                               const TopTools_MapOfShape& anAvoidSubshMap)
118 {
119   Standard_Integer j, nSub, nRest;
120   TopOpeBRepDS_DataMapOfShapeState aMapSS, aMapSS1;
121 
122 
123   TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState anItSS (aSplShapesState);
124   for (; anItSS.More(); anItSS.Next()) {
125     const TopoDS_Shape& aShape= anItSS.Key();
126     TopAbs_State aState       = anItSS.Value();
127     TopTools_IndexedMapOfShape aSubshapes;
128     TopExp::MapShapes (aShape, aSubshEnum, aSubshapes);
129     nSub=aSubshapes.Extent();
130     for (j=1; j<=nSub; j++)
131       if (!anAvoidSubshMap.Contains(aSubshapes(j))) // MSV: enforce subshapes avoidance
132         aMapSS.Bind (aSubshapes(j), aState);
133   }
134 
135   aMapSS1=aMapSS;
136 
137   // 1. Build the Map of ShapesAndAncestors for ShapesToRest
138   TopTools_IndexedDataMapOfShapeListOfShape aMapSubshAnc;
139   nRest=aShapesToRestMap.Extent();
140   for (j=1; j<=nRest; j++)
141     TopExp::MapShapesAndAncestors(aShapesToRestMap(j), aSubshEnum, aShapeEnum, aMapSubshAnc);
142 
143   // 2. Make Map Of all subshapes  aMapSS
144   TopTools_MapOfShape aProcessedSubshapes;
145   anItSS.Initialize (aMapSS1);
146   for (; anItSS.More(); anItSS.Next()) {
147     const TopoDS_Shape& aSubsh = anItSS.Key();
148     TopAbs_State aState        = anItSS.Value();
149     if (aMapSubshAnc.Contains (aSubsh)) {
150       aProcessedSubshapes.Add (aSubsh);
151       FindState (aSubsh, aState, aSubshEnum, aMapSubshAnc, aProcessedSubshapes, aMapSS);
152     }
153   }
154 
155   // 3. Propagate the states on ShapesToRestMap
156   TopoDS_Shape aNullShape;
157   TopTools_MapOfShape aNonPassedShapes;
158   nRest=aShapesToRestMap.Extent();
159   for (j=1; j<=nRest; j++) {
160     const TopoDS_Shape& aS=aShapesToRestMap.FindKey(j);
161     TopTools_IndexedMapOfShape aSubshMap;
162     TopExp::MapShapes (aS, aSubshEnum, aSubshMap);
163     const TopoDS_Shape& aSubsh=aSubshMap(1);
164     if (aMapSS.IsBound(aSubsh)) {
165       TopAbs_State aState=aMapSS.Find(aSubsh);
166 
167       if (aState==TopAbs_ON) {
168 	aState=aShapeClassifier.StateShapeReference(aS, aNullShape);
169       }
170       // Add the Rest Shape to aMapOfShapeWithState
171       TopOpeBRepDS_ShapeWithState aShapeWithState;
172       aShapeWithState.SetState (aState);
173       aShapeWithState.SetIsSplitted (Standard_False);
174       aMapOfShapeWithState.Add (aS, aShapeWithState);
175     }
176 
177     else {
178       aNonPassedShapes.Add(aS);
179     }
180   }
181 
182   // 4. Define the states for aNonPassedShapes
183   //   (for faces themselves and for theirs Wires, Edges):
184   if (aNonPassedShapes.Extent()) {
185     // Build the Map of ShapesAndAncestors for aNonPassedShapes
186     aMapSubshAnc.Clear();
187     TopTools_MapIteratorOfMapOfShape aMapIt;
188     aMapIt.Initialize (aNonPassedShapes);
189     for (; aMapIt.More(); aMapIt.Next())
190       TopExp::MapShapesAndAncestors (aMapIt.Key(), aSubshEnum, aShapeEnum, aMapSubshAnc);
191 
192     aMapSS.Clear();
193     aMapIt.Initialize (aNonPassedShapes);
194     for (; aMapIt.More(); aMapIt.Next()) {
195       // Face
196       const TopoDS_Shape& aNonPassedShape=aMapIt.Key();
197 
198       if (!aMapSS.IsBound(aNonPassedShape)) {
199 	TopAbs_State aState = FindStateThroughVertex (aNonPassedShape, aShapeClassifier,
200                                                       aMapOfShapeWithState,anAvoidSubshMap);
201 	aMapSS.Bind (aNonPassedShape, aState);
202 
203 	// First Subshape
204 	TopTools_IndexedMapOfShape aTmpMap;
205 	TopExp::MapShapes (aNonPassedShape, aSubshEnum, aTmpMap);
206 	TopoDS_Shape aFirstSubsh;
207         for (j=1; j <= aTmpMap.Extent() && aFirstSubsh.IsNull(); j++)
208           if (!anAvoidSubshMap.Contains(aTmpMap(j)))
209             aFirstSubsh = aTmpMap(j);
210         if (aFirstSubsh.IsNull()) continue;
211 	aMapSS.Bind (aFirstSubsh, aState);
212 
213 	// Propagation of aState for subshapes
214 	TopTools_MapOfShape aMapProcessedSubsh;
215 	if (aSubshEnum==TopAbs_EDGE)
216 	  FindState1 (aFirstSubsh, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
217 	else // if (aSubshEnum==TopAbs_VERTEX)
218 	  FindState2 (aFirstSubsh, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
219       }
220     }
221 
222     // Fill aShapeWithState
223     TopOpeBRepDS_ShapeWithState aShapeWithState;
224     aShapeWithState.SetIsSplitted (Standard_False);
225     TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState anII(aMapSS);
226     for (; anII.More(); anII.Next()) {
227       aShapeWithState.SetState (anII.Value());
228       if (anII.Key().ShapeType() != TopAbs_VERTEX)
229 	aMapOfShapeWithState.Add (anII.Key(), aShapeWithState);
230     }
231   }
232 }
233 
234 //=======================================================================
235 //function :  TopOpeBRepBuild_Tools::FindState2
236 //purpose  :
237 //=======================================================================
FindState2(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)238   void TopOpeBRepBuild_Tools::FindState2 (const TopoDS_Shape& aSubsh,
239 					  const TopAbs_State aState,
240 					  const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
241 					  TopTools_MapOfShape& aMapProcessedSubsh,
242 					  TopOpeBRepDS_DataMapOfShapeState& aMapSS)
243 {
244   Standard_Integer i, nSub;
245   const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
246   TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
247   for (; anIt.More(); anIt.Next()) {
248     //Shape
249     const TopoDS_Shape& aShape=anIt.Value();
250     aMapSS.Bind (aShape, aState);
251 
252     //Subshape
253     TopTools_IndexedMapOfShape aSubshMap;
254     TopExp::MapShapes (aShape, TopAbs_VERTEX, aSubshMap);
255     nSub=aSubshMap.Extent();
256     for (i=1; i<=nSub; i++) {
257       const TopoDS_Shape& aSS=aSubshMap(i);
258       if (! aMapProcessedSubsh.Contains(aSS)) {
259 	aMapProcessedSubsh.Add(aSS);
260 	aMapSS.Bind (aSS, aState);
261 	FindState2 (aSS, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
262       }
263     }
264   }
265 }
266 
267 //=======================================================================
268 //function :TopOpeBRepBuild_Tools::FindState1
269 //purpose  :
270 //=======================================================================
FindState1(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)271   void TopOpeBRepBuild_Tools::FindState1 (const TopoDS_Shape& aSubsh,
272 					  const TopAbs_State aState,
273 					  const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
274 					  TopTools_MapOfShape& aMapProcessedSubsh,
275 					  TopOpeBRepDS_DataMapOfShapeState& aMapSS)
276 {
277   Standard_Integer i, nSub, j, nW;
278   const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
279   TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
280   for (; anIt.More(); anIt.Next()) {
281     //Face
282     const TopoDS_Shape& aShape=anIt.Value();
283     aMapSS.Bind (aShape, aState);
284     //Wire
285     TopTools_IndexedMapOfShape aWireMap;
286     TopExp::MapShapes (aShape, TopAbs_WIRE, aWireMap);
287     nW=aWireMap.Extent();
288     for (j=1; j<=nW; j++) aMapSS.Bind (aWireMap(j), aState);
289     //Edge
290     TopTools_IndexedMapOfShape aSubshMap;
291     TopExp::MapShapes (aShape, TopAbs_EDGE, aSubshMap);
292     nSub=aSubshMap.Extent();
293     for (i=1; i<=nSub; i++) {
294       const TopoDS_Shape& aSS=aSubshMap(i);
295       if (! aMapProcessedSubsh.Contains(aSS)) {
296 	aMapProcessedSubsh.Add(aSS);
297 	aMapSS.Bind (aSS, aState);
298 	FindState1 (aSS, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
299       }
300     }
301   }
302 }
303 
304 //=======================================================================
305 //function :TopOpeBRepBuild_Tools::FindStateThroughVertex
306 //purpose  :
307 //=======================================================================
FindStateThroughVertex(const TopoDS_Shape & aShape,TopOpeBRepTool_ShapeClassifier & aShapeClassifier,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState,const TopTools_MapOfShape & anAvoidSubshMap)308   TopAbs_State TopOpeBRepBuild_Tools::FindStateThroughVertex (const TopoDS_Shape& aShape,
309 		      TopOpeBRepTool_ShapeClassifier& aShapeClassifier,
310 		      TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState,
311                       const TopTools_MapOfShape& anAvoidSubshMap)
312 {
313   TopTools_IndexedMapOfShape aSubshMap;
314   TopExp::MapShapes (aShape, TopAbs_VERTEX, aSubshMap);
315 
316   TopoDS_Shape aSubsh;
317   Standard_Integer i;
318   for (i=1; i <= aSubshMap.Extent() && aSubsh.IsNull(); i++)
319     if (!anAvoidSubshMap.Contains (aSubshMap(i)) )
320       aSubsh = aSubshMap(i);
321   if (aSubsh.IsNull()) {
322     // try an edge
323     aSubshMap.Clear();
324     TopExp::MapShapes (aShape, TopAbs_EDGE, aSubshMap);
325     for (i=1; i <= aSubshMap.Extent() && aSubsh.IsNull(); i++)
326       if (!anAvoidSubshMap.Contains (aSubshMap(i)) )
327         aSubsh = aSubshMap(i);
328     if (aSubsh.IsNull()) {
329 #ifdef OCCT_DEBUG
330       std::cout<<"FindStateThroughVertex: warning: all vertices are avoided"<<std::endl;
331 #endif
332       return TopAbs_UNKNOWN;    // failure
333     }
334   }
335 
336   TopoDS_Shape aNullShape;
337   TopAbs_State aState=aShapeClassifier.StateShapeReference(aSubsh, aNullShape);
338   TopOpeBRepDS_ShapeWithState aShapeWithState;
339   aShapeWithState.SetState (aState);
340   aShapeWithState.SetIsSplitted (Standard_False);
341   aMapOfShapeWithState.Add(aShape, aShapeWithState);
342   SpreadStateToChild (aShape, aState, aMapOfShapeWithState);
343   return aState;
344 
345 }
346 
347 
348 //=======================================================================
349 //function :TopOpeBRepBuild_Tools::SpreadStateToChild
350 //purpose  :
351 //=======================================================================
SpreadStateToChild(const TopoDS_Shape & aShape,const TopAbs_State aState,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState)352   void  TopOpeBRepBuild_Tools::SpreadStateToChild (const TopoDS_Shape& aShape,
353 						   const TopAbs_State aState,
354 						   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState)
355 {
356   TopTools_IndexedMapOfShape aChildMap;
357   TopExp::MapShapes (aShape, TopAbs_FACE, aChildMap);
358   TopExp::MapShapes (aShape, TopAbs_WIRE, aChildMap);
359   TopExp::MapShapes (aShape, TopAbs_EDGE, aChildMap);
360 
361   TopOpeBRepDS_ShapeWithState aShapeWithState;
362   aShapeWithState.SetState (aState);
363   aShapeWithState.SetIsSplitted (Standard_False);
364 
365   Standard_Integer i, n=aChildMap.Extent();
366   for (i=1; i<=n; i++) {
367     aMapOfShapeWithState.Add(aChildMap(i), aShapeWithState);
368   }
369 }
370 
371 //=======================================================================
372 //function :TopOpeBRepBuild_Tools::PropagateStateForWires
373 //purpose  :
374 //=======================================================================
PropagateStateForWires(const TopTools_IndexedMapOfShape & aFacesToRestMap,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState)375   void TopOpeBRepBuild_Tools::PropagateStateForWires(const TopTools_IndexedMapOfShape& aFacesToRestMap,
376 						     TopOpeBRepDS_IndexedDataMapOfShapeWithState&
377 						     aMapOfShapeWithState)
378 {
379   Standard_Integer i, j, nF, nW, k, nE;
380 
381   nF=aFacesToRestMap.Extent();
382   for (i=1; i<=nF; i++) {
383     const TopoDS_Shape& aF=aFacesToRestMap(i);
384     if (aMapOfShapeWithState.Contains (aF)) {
385       const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(aF);
386       TopAbs_State aSt=aSWS.State();
387 
388       TopTools_IndexedMapOfShape aWireMap;
389       TopExp::MapShapes (aF, TopAbs_WIRE, aWireMap);
390       nW=aWireMap.Extent();
391       for (j=1; j<=nW; j++) {
392 	const TopoDS_Shape& aW=aWireMap(j);
393 	TopOpeBRepDS_ShapeWithState aWireSWS;
394 	aWireSWS.SetState(aSt);
395 	aWireSWS.SetIsSplitted (Standard_False);
396 	aMapOfShapeWithState.Add(aW, aWireSWS);
397 
398 	TopTools_IndexedMapOfShape aEdgeMap;
399 	TopExp::MapShapes (aW, TopAbs_EDGE, aEdgeMap);
400 	nE=aEdgeMap.Extent();
401 	for (k=1; k<=nE; k++) {
402 	  const TopoDS_Shape& aE=aEdgeMap(k);
403 	  if (!aMapOfShapeWithState.Contains (aE)) {
404 	    TopOpeBRepDS_ShapeWithState anEdgeSWS;
405 	    anEdgeSWS.SetState(aSt);
406 	    anEdgeSWS.SetIsSplitted (Standard_False);
407 	    aMapOfShapeWithState.Add(aE, anEdgeSWS);
408 	  }
409 	}
410       }
411     }
412   }
413 }
414 
415 //=======================================================================
416 //function :TopOpeBRepBuild_Tools:: GetNormalToFaceOnEdge
417 //purpose  :
418 //=======================================================================
GetNormalToFaceOnEdge(const TopoDS_Face & aFObj,const TopoDS_Edge & anEdgeObj,gp_Vec & aNormal)419   void TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (const TopoDS_Face& aFObj,
420 						     const TopoDS_Edge& anEdgeObj,
421 						     gp_Vec& aNormal)
422 {
423   TopoDS_Edge aEd=anEdgeObj;
424   TopoDS_Face aFS=aFObj;
425   Standard_Real f2 = 0., l2 = 0., tolpc = 0., f = 0., l = 0., par = 0.;
426   Handle(Geom2d_Curve) C2D=FC2D_CurveOnSurface(aEd,aFS,f2,l2,tolpc, Standard_True);
427 
428   BRepAdaptor_Curve  aCA(aEd);
429   f=aCA.FirstParameter();
430   l=aCA.LastParameter();
431   par= f*PAR_T + (1 - PAR_T)*l;
432 
433   gp_Pnt2d aUV1 ;
434   C2D -> D0(par, aUV1);
435 
436   gp_Pnt aP;
437   gp_Vec  aTg1, aTg2;
438   BRepAdaptor_Surface aSA1(aFS);
439   aSA1.D1(aUV1.X(), aUV1.Y(), aP, aTg1, aTg2);
440   aNormal = aTg1^aTg2;
441 }
442 
443 //=======================================================================
444 //function : TopOpeBRepBuild_Tools::GetNormalInNearestPoint
445 //purpose  :
446 //=======================================================================
GetNormalInNearestPoint(const TopoDS_Face & F,const TopoDS_Edge & E,gp_Vec & aNormal)447 void TopOpeBRepBuild_Tools::GetNormalInNearestPoint(const TopoDS_Face& F,
448 					       const TopoDS_Edge& E,
449 					       gp_Vec& aNormal)
450 {
451   Standard_Real f2 = 0., l2 = 0., tolpc = 0., par = 0.;
452 
453   gp_Vec2d aTangent;
454 
455   Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(E, F, f2, l2, tolpc, Standard_True);
456 
457 
458   par = f2*PAR_T + (1 - PAR_T)*l2;
459 
460   gp_Pnt2d aP;
461   C2D -> D1(par, aP, aTangent);
462 
463   Standard_Real Xnorm = -aTangent.Y();
464   Standard_Real Ynorm = aTangent.X();
465 
466   Standard_Real step = TopOpeBRepTool_TOOL::minDUV(F); step *= 1e-2;
467 
468   gp_Vec2d aPV(aP.X(), aP.Y());
469   gp_Dir2d aStepV(Xnorm, Ynorm);
470   gp_Vec2d aNorm2d = aPV + gp_Vec2d(step*aStepV);
471 
472   Standard_Real newU = aNorm2d.X();
473   Standard_Real newV = aNorm2d.Y();
474   gp_Vec  aTg1, aTg2;
475   gp_Pnt aP1;
476 
477   BRepAdaptor_Surface BS(F);
478   BS.D1(newU, newV, aP1, aTg1, aTg2);
479 
480 
481   gp_Pnt2d aP2d(newU, newV);
482   BRepTopAdaptor_FClass2d FC(F, Precision::PConfusion());
483   TopAbs_State aState = FC.Perform(aP2d);
484 
485   //point out of face: try to go at another direction
486   if(aState == TopAbs_OUT) {
487     aStepV.Reverse();
488     aNorm2d = aPV + gp_Vec2d(step*aStepV);
489 
490     newU = aNorm2d.X();
491     newV = aNorm2d.Y();
492 
493     BS.D1(newU, newV, aP1, aTg1, aTg2);
494 
495 //in principle, we must check again
496 //    aP2d.SetX(newU); aP2d.SetY(newV);
497 //    BRepClass_FaceClassifier FC(Fex, aP2d, 1e-7);
498 //    TopAbs_State aState = FC.State();
499   }
500 
501   aNormal = aTg1^aTg2;
502 }
503 
504 
505 //=======================================================================
506 //function : TopOpeBRepBuild_Tools::GetTangentToEdgeEdge
507 //purpose  :
508 //=======================================================================
GetTangentToEdgeEdge(const TopoDS_Face &,const TopoDS_Edge & anEdgeObj,const TopoDS_Edge & aOriEObj,gp_Vec & aTangent)509 Standard_Boolean TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (const TopoDS_Face& ,//aFObj,
510 							      const TopoDS_Edge& anEdgeObj,
511 							      const TopoDS_Edge& aOriEObj,
512 							      gp_Vec& aTangent)
513 {
514 
515   if (BRep_Tool::Degenerated(aOriEObj) ||
516       BRep_Tool::Degenerated(anEdgeObj)) {
517     return TopOpeBRepBuild_Tools::GetTangentToEdge (anEdgeObj, aTangent) ;
518   }
519 
520   TopoDS_Edge aEd=anEdgeObj, aEOri = aOriEObj;
521 
522   Standard_Real f = 0., l = 0., par = 0., parOri = 0.;
523 
524   BRepAdaptor_Curve  aCA(aEd);
525   BRepAdaptor_Curve  aCAOri(aEOri);
526 
527   f=aCA.FirstParameter();
528   l=aCA.LastParameter();
529 
530   par= f*PAR_T + (1 - PAR_T)*l;
531 
532   gp_Pnt aP;
533   gp_Vec aTgPiece;
534   aCA.D1(par, aP, aTgPiece);
535   aTangent = aTgPiece;
536 
537   gp_Pnt aPOri;
538   gp_Vec aTgOri;
539   /////
540   Handle (Geom_Curve) GCOri=aCAOri.Curve().Curve();
541   Handle (Geom_Curve) aCopyCurve = Handle(Geom_Curve)::DownCast(GCOri -> Copy());
542 
543   const TopLoc_Location& aLoc = aEOri.Location();
544   gp_Trsf aTrsf = aLoc.Transformation();
545   aCopyCurve -> Transform(aTrsf);
546 
547   GeomAPI_ProjectPointOnCurve aPP(aP, aCopyCurve, aCopyCurve->FirstParameter(), aCopyCurve->LastParameter());
548 #ifdef OCCT_DEBUG
549 //  gp_Pnt aNP = aPP.NearestPoint();
550 #endif
551   parOri = aPP.LowerDistanceParameter();
552 
553   aCopyCurve -> D1(parOri, aPOri, aTgOri);// aPOri must be equal aNP !
554   //printf(" aNP  ={%lf, %lf, %lf}\n", aNP.X(), aNP.Y(), aNP.Z());
555   //printf(" aPOri={%lf, %lf, %lf}\n", aPOri.X(), aPOri.Y(), aPOri.Z());
556   if (aEd.Orientation() == TopAbs_REVERSED)
557     aTangent.Reverse();
558 
559   if(aTgOri*aTgPiece < 0.) {
560     aTangent.Reverse();
561     return Standard_True;
562   }
563   return Standard_False;
564 }
565 
566 
567 //=======================================================================
568 //function : TopOpeBRepBuild_Tools::GetTangentToEdge
569 //purpose  :
570 //=======================================================================
GetTangentToEdge(const TopoDS_Edge & anEdgeObj,gp_Vec & aTangent)571 Standard_Boolean TopOpeBRepBuild_Tools::GetTangentToEdge (const TopoDS_Edge& anEdgeObj,
572 							  gp_Vec& aTangent)
573 {
574   TopoDS_Edge aEd=anEdgeObj;
575 
576   Standard_Real f = 0., l = 0., par = 0.;
577 
578   BRepAdaptor_Curve  aCA(aEd);
579 
580   f=aCA.FirstParameter();
581   l=aCA.LastParameter();
582 
583   par= f*PAR_T + (1 - PAR_T)*l;
584   gp_Pnt aP;
585   aCA.D1(par, aP, aTangent);
586 
587   return Standard_True;
588 
589 }
590 
591 //=======================================================================
592 //function : TopOpeBRepBuild_Tools::GetAdjacentFace
593 //purpose  :
594 //=======================================================================
GetAdjacentFace(const TopoDS_Shape & aFaceObj,const TopoDS_Shape & anEObj,const TopTools_IndexedDataMapOfShapeListOfShape & anEdgeFaceMap,TopoDS_Shape & anAdjFaceObj)595 Standard_Boolean TopOpeBRepBuild_Tools::GetAdjacentFace (const TopoDS_Shape& aFaceObj,
596 							 const TopoDS_Shape& anEObj,
597 							 const TopTools_IndexedDataMapOfShapeListOfShape& anEdgeFaceMap,
598 							 TopoDS_Shape& anAdjFaceObj)
599 {
600   const TopTools_ListOfShape& aListOfAdjFaces=anEdgeFaceMap.FindFromKey(anEObj);
601   TopTools_ListIteratorOfListOfShape anIt(aListOfAdjFaces);
602   TopoDS_Shape anAdjShape;
603   for (; anIt.More(); anIt.Next()) {
604     if (anIt.Value()!=aFaceObj) {
605       anAdjShape=anIt.Value();
606       break;
607     }
608   }
609 
610   if (!anAdjShape.IsNull()) {
611     anAdjFaceObj=TopoDS::Face(anAdjShape);
612     return Standard_True;
613   }
614   else {
615     return Standard_False;
616   }
617 }
618 
619 //=======================================================================
620 //function : UpdatePCurves
621 //purpose  :
622 //=======================================================================
UpdatePCurves(const TopoDS_Wire & aWire,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)623 void TopOpeBRepBuild_Tools::UpdatePCurves(const TopoDS_Wire& aWire,
624 					  const TopoDS_Face& fromFace,
625 					  const TopoDS_Face& toFace)
626 {
627   TopExp_Explorer aExp(aWire, TopAbs_EDGE);
628 
629   for(; aExp.More(); aExp.Next()) {
630     TopoDS_Shape aEdge = aExp.Current();
631     UpdateEdgeOnFace(TopoDS::Edge(aEdge), fromFace, toFace);
632   }
633 }
634 
635 //=======================================================================
636 //function : UpdateEdgeOnFace
637 //purpose  :
638 //=======================================================================
UpdateEdgeOnFace(const TopoDS_Edge & aEdgeToUpdate,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)639 void TopOpeBRepBuild_Tools::UpdateEdgeOnFace(const TopoDS_Edge& aEdgeToUpdate,
640 					     const TopoDS_Face& fromFace,
641 					     const TopoDS_Face& toFace)
642 {
643   BRep_Builder BB;
644 
645   Standard_Real tolE = BRep_Tool::Tolerance(TopoDS::Edge(aEdgeToUpdate));
646   Standard_Real f2 = 0.,l2 = 0.,tolpc = 0.;
647   Handle(Geom2d_Curve) C2D;
648 
649   if(BRep_Tool::Degenerated(aEdgeToUpdate)) {
650     //we can not compute PCurve for Degenerated Edge
651     //so we take as it was on old face and after (in CorrectFace2D)
652     // we will adjust this PCurve
653     C2D = FC2D_CurveOnSurface(aEdgeToUpdate, fromFace,
654 			      f2, l2, tolpc, Standard_True);
655     Standard_Real tol = Max(tolE, tolpc);
656     Handle(Geom2d_Curve) C2Dn = Handle(Geom2d_Curve)::DownCast(C2D -> Copy());
657     Handle(Geom2d_TrimmedCurve) newC2D = new Geom2d_TrimmedCurve(C2Dn, f2, l2);
658     BB.UpdateEdge(aEdgeToUpdate ,newC2D, toFace , tol);
659 
660   }
661   else { //not degenerated edge
662 
663     if(BRep_Tool::IsClosed(aEdgeToUpdate, fromFace)) {
664       UpdateEdgeOnPeriodicalFace(aEdgeToUpdate, fromFace, toFace);
665     }
666     else {
667       C2D = FC2D_CurveOnSurface(aEdgeToUpdate, toFace , f2, l2, tolpc, Standard_True);
668       Standard_Real tol = Max(tolE,tolpc);
669       BB.UpdateEdge(aEdgeToUpdate ,C2D, toFace , tol);
670     }
671   }
672 }
673 
674 //=======================================================================
675 //function : UpdateEdgeOnPeriodicalFace
676 //purpose  :
677 //=======================================================================
UpdateEdgeOnPeriodicalFace(const TopoDS_Edge & aEdgeToUpdate,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)678 void TopOpeBRepBuild_Tools::UpdateEdgeOnPeriodicalFace(const TopoDS_Edge& aEdgeToUpdate,
679 						       const TopoDS_Face& fromFace,
680 						       const TopoDS_Face& toFace)
681 {
682   Standard_Boolean DiffOriented = Standard_False;
683   BRep_Builder BB;
684   TopoDS_Edge newE = aEdgeToUpdate; //newE.Orientation(TopAbs_FORWARD);
685   TopoDS_Face fFace = fromFace;   //fFace.Orientation(TopAbs_FORWARD);
686   TopoDS_Face tFace = toFace; //tFace.Orientation(TopAbs_FORWARD);
687   Standard_Real fc = 0., lc = 0.;
688 
689   Handle(Geom2d_Curve) cc = BRep_Tool::CurveOnSurface(newE, tFace, fc, lc);
690 
691   if(!cc.IsNull()) {
692     //std::cout << "Pcurves exist" << std::endl;
693     return;
694   }
695 
696   gp_Vec aN1, aN2;
697   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(fromFace),
698 					       TopoDS::Edge(aEdgeToUpdate), aN1);
699 
700 
701   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(toFace),
702 					       TopoDS::Edge(aEdgeToUpdate), aN2);
703 
704   if(aN1*aN2 < 0)
705     DiffOriented = Standard_True;
706 
707   Standard_Real tolE = BRep_Tool::Tolerance(newE);
708   Standard_Real f2 = 0., l2 = 0., tolpc = 0., tol = 0.;
709 
710   //first  PCurve
711   Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(newE,
712 						 tFace, f2,
713 						 l2, tolpc, Standard_True);
714 
715   tol = Max(tolpc, tolE);
716 
717   BRepAdaptor_Surface aBAS(fFace);
718   gp_Vec2d aTrV;
719 
720   Standard_Real ff = 0., lf = 0., fr = 0., lr = 0.;
721   gp_Pnt2d aUVf, aUVr;
722 
723   Handle(Geom2d_Curve) oldC2DFor = BRep_Tool::CurveOnSurface(newE, //FC2D_CurveOnSurface(newE,
724 						       fFace, ff,
725 						       lf);//, tolpc, Standard_True);
726   newE.Reverse();
727   Handle(Geom2d_Curve) oldC2DRev = BRep_Tool::CurveOnSurface(newE, //FC2D_CurveOnSurface(newE,
728 						       fFace, fr,
729 						       lr);//, tolpc, Standard_True);
730 
731   oldC2DFor -> D0(ff, aUVf);
732   oldC2DRev -> D0(fr, aUVr);
733 
734   if(!DiffOriented)
735     aTrV = gp_Vec2d(aUVf, aUVr);
736   else
737     aTrV = gp_Vec2d(aUVr, aUVf);
738 
739   gp_Vec2d aux(gp_Pnt2d(0., 0.), gp_Pnt2d(1., 1.));
740   Standard_Real scalar = aux*aTrV;
741   Standard_Boolean dir = (scalar >= 0.) ? Standard_True : Standard_False;
742 
743   //compute right order of pcurves
744   gp_Vec2d aYVec(gp_Pnt2d(0., 0.), gp_Pnt2d(0., 1.));
745   gp_Pnt2d aUVfv, aUVlv;
746   C2D -> D0(f2, aUVfv);
747   C2D -> D0(l2, aUVlv);
748   gp_Vec2d C2DVec(aUVfv, aUVlv);
749 
750   Standard_Boolean firstOrder = Standard_True;
751   scalar = aYVec*C2DVec;
752   if(fabs(scalar) <= 1e-10) {// compute along X axe
753     gp_Vec2d aXVec(gp_Pnt2d(0., 0.), gp_Pnt2d(1., 0.));
754     scalar = aXVec*C2DVec;
755     firstOrder = (scalar >= 0.) ? Standard_True : Standard_False;
756   }
757   else
758     firstOrder = (scalar > 0.) ? Standard_False : Standard_True;
759 
760   Handle(Geom2d_Curve) aTrC = Handle(Geom2d_Curve)::DownCast(C2D->Copy());
761   aTrC -> Translate(aTrV);
762 
763   if(dir) {
764     if(firstOrder)
765       BB.UpdateEdge(aEdgeToUpdate, C2D, aTrC, toFace, tol);
766     else
767       BB.UpdateEdge(aEdgeToUpdate, aTrC, C2D, toFace, tol);
768   }
769   else {
770     if(!firstOrder)
771       BB.UpdateEdge(aEdgeToUpdate, C2D, aTrC, toFace, tol);
772     else
773       BB.UpdateEdge(aEdgeToUpdate, aTrC, C2D, toFace, tol);
774   }
775 }
776 
777 //=======================================================================
778 //function : TopOpeBRepBuild_Tools::IsDegEdgesTheSame
779 //purpose  :
780 //=======================================================================
IsDegEdgesTheSame(const TopoDS_Shape & anE1,const TopoDS_Shape & anE2)781 Standard_Boolean TopOpeBRepBuild_Tools::IsDegEdgesTheSame (const TopoDS_Shape& anE1,
782 							   const TopoDS_Shape& anE2)
783 {
784   TopTools_IndexedMapOfShape aVMap1, aVMap2;
785   TopExp::MapShapes(anE1, TopAbs_VERTEX, aVMap1);
786   TopExp::MapShapes(anE2, TopAbs_VERTEX, aVMap2);
787 
788   if (!aVMap1.Extent() || !aVMap2.Extent())
789     return Standard_False;
790 
791   if (aVMap1(1).IsSame(aVMap2(1)))
792     return Standard_True;
793   else
794     return Standard_False;
795 }
796 
797 //=======================================================================
798 //function : NormalizeFace
799 //purpose  : remove all INTERNAL and EXTERNAL edges from the face
800 //=======================================================================
NormalizeFace(const TopoDS_Shape & oldFace,TopoDS_Shape & corrFace)801 void TopOpeBRepBuild_Tools::NormalizeFace(const TopoDS_Shape& oldFace,
802 					  TopoDS_Shape& corrFace)
803 {
804   Standard_Real tolF1;
805 
806   TopLoc_Location Loc;
807   TopoDS_Face aF1 = TopoDS::Face(oldFace),
808               aNewFace;
809 
810   aF1.Orientation(TopAbs_FORWARD);
811 
812   Handle(Geom_Surface) Surf = BRep_Tool::Surface(aF1, Loc);
813   tolF1 = BRep_Tool::Tolerance(aF1);
814   BRep_Builder BB;
815   BB.MakeFace(aNewFace, Surf, Loc, tolF1);
816 
817   TopExp_Explorer aFExp(aF1, TopAbs_WIRE);
818   for (; aFExp.More(); aFExp.Next()) {
819     Standard_Integer NbGoodEdges = 0;
820     TopoDS_Shape aWire=aFExp.Current();
821     aWire.Orientation(TopAbs_FORWARD);
822     TopoDS_Wire aNewWire;
823 
824     BB.MakeWire(aNewWire);
825 
826     TopExp_Explorer aWExp(aWire, TopAbs_EDGE);
827     for (; aWExp.More(); aWExp.Next()) {
828       TopoDS_Shape anEdge=aWExp.Current();
829 
830       if (anEdge.Orientation()==TopAbs_EXTERNAL ||
831 	  anEdge.Orientation()==TopAbs_INTERNAL)
832 	continue;
833 
834       BB.Add (aNewWire, TopoDS::Edge(anEdge));
835       NbGoodEdges++;
836     }
837     //keep wire  orientation
838     aNewWire.Orientation(aFExp.Current().Orientation());//aWire.Orientation());
839 
840     if(NbGoodEdges) //we add new wire only if it contains at least one edge
841       BB.Add (aNewFace, aNewWire);
842   }
843   //keep face  orientation
844   aNewFace.Orientation(oldFace.Orientation());
845 
846   corrFace = aNewFace;
847 }
848 
849 
850 //=======================================================================
851 //function : CorrectFace2d
852 //purpose  : adjust PCurves of periodical face in 2d
853 //=======================================================================
CorrectFace2d(const TopoDS_Shape & oldFace,TopoDS_Shape & corrFace,const TopTools_IndexedMapOfOrientedShape & aSourceShapes,TopTools_IndexedDataMapOfShapeShape & aMapOfCorrect2dEdges)854 void TopOpeBRepBuild_Tools::CorrectFace2d (const TopoDS_Shape& oldFace,
855 					   TopoDS_Shape& corrFace,
856 					   const TopTools_IndexedMapOfOrientedShape& aSourceShapes,
857 					   TopTools_IndexedDataMapOfShapeShape& aMapOfCorrect2dEdges)
858 {
859   TopOpeBRepBuild_CorrectFace2d aCorrectFace2d(TopoDS::Face(oldFace),
860 					       aSourceShapes,
861 					       aMapOfCorrect2dEdges);
862 
863 
864   aCorrectFace2d.Perform();
865   corrFace=oldFace;
866 }
867