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