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