0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / HLRBRep / HLRBRep_PolyAlgo.cxx
1 // Created on: 1995-05-05
2 // Created by: Christophe MARION
3 // Copyright (c) 1995-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 #include <HLRAlgo_PolyAlgo.hxx>
18
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepLib_MakeEdge.hxx>
22 #include <CSLib.hxx>
23 #include <CSLib_DerivativeStatus.hxx>
24 #include <CSLib_NormalStatus.hxx>
25 #include <Geom_RectangularTrimmedSurface.hxx>
26 #include <Geom_Surface.hxx>
27 #include <HLRAlgo_BiPoint.hxx>
28 #include <HLRAlgo_EdgeStatus.hxx>
29 #include <HLRAlgo_PolyData.hxx>
30 #include <HLRAlgo_PolyInternalData.hxx>
31 #include <HLRAlgo_PolyMask.hxx>
32 #include <HLRAlgo_PolyShellData.hxx>
33 #include <HLRBRep_PolyAlgo.hxx>
34 #include <Poly_Polygon3D.hxx>
35 #include <Poly_PolygonOnTriangulation.hxx>
36 #include <Poly_Triangulation.hxx>
37 #include <Precision.hxx>
38 #include <Standard_ErrorHandler.hxx>
39 #include <Standard_OutOfRange.hxx>
40 #include <Standard_Stream.hxx>
41 #include <Standard_Type.hxx>
42 #include <TopExp.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopTools_Array1OfShape.hxx>
48 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
49
50 IMPLEMENT_STANDARD_RTTIEXT(HLRBRep_PolyAlgo,Standard_Transient)
51
52 enum
53 {
54   NMsk_Vert =  1,
55   NMsk_OutL =  2,
56   NMsk_Norm =  4,
57   NMsk_Fuck =  8,
58   NMsk_Edge = 16,
59   NMsk_Move = 32
60 };
61
62 #ifdef OCCT_DEBUG
63 static Standard_Integer DoTrace = Standard_False; 
64 static Standard_Integer DoError = Standard_False; 
65 #endif
66 //=======================================================================
67 //function : HLRBRep_PolyAlgo
68 //purpose  :
69 //=======================================================================
70 HLRBRep_PolyAlgo::HLRBRep_PolyAlgo()
71 : myDebug     (Standard_False),
72   myTolSta    (0.1),
73   myTolEnd    (0.9),
74   myTolAngular(0.001)
75 {
76   myAlgo = new HLRAlgo_PolyAlgo();
77 }
78
79 //=======================================================================
80 //function : HLRBRep_PolyAlgo
81 //purpose  :
82 //=======================================================================
83 HLRBRep_PolyAlgo::HLRBRep_PolyAlgo (const Handle(HLRBRep_PolyAlgo)& theOther)
84 {
85   myDebug      = theOther->Debug();
86   myTolAngular = theOther->TolAngular();
87   myTolSta     = theOther->TolCoef();
88   myTolEnd     = 1.0 - myTolSta;
89   myAlgo       = theOther->Algo();
90   myProj       = theOther->Projector();
91
92   const Standard_Integer aNbShapes = theOther->NbShapes();
93   for (Standard_Integer i = 1; i <= aNbShapes; ++i)
94   {
95     Load (theOther->Shape (i));
96   }
97 }
98
99 //=======================================================================
100 //function : HLRBRep_PolyAlgo
101 //purpose  :
102 //=======================================================================
103 HLRBRep_PolyAlgo::HLRBRep_PolyAlgo (const TopoDS_Shape& theShape)
104 : myDebug     (Standard_False),
105   myTolSta    (0.1),
106   myTolEnd    (0.9),
107   myTolAngular(0.001)
108 {
109   myShapes.Append (theShape);
110   myAlgo = new HLRAlgo_PolyAlgo();
111 }
112
113 //=======================================================================
114 //function : Shape
115 //purpose  :
116 //=======================================================================
117 TopoDS_Shape& HLRBRep_PolyAlgo::Shape (const Standard_Integer theIndex)
118 {
119   return myShapes.ChangeValue (theIndex);
120 }
121
122 //=======================================================================
123 //function : Remove
124 //purpose  :
125 //=======================================================================
126 void HLRBRep_PolyAlgo::Remove (const Standard_Integer theIndex)
127 {
128   Standard_OutOfRange_Raise_if (theIndex == 0 || theIndex > myShapes.Length(),
129                                 "HLRBRep_PolyAlgo::Remove : unknown Shape");
130   myShapes.Remove (theIndex);
131   myAlgo->Clear();
132   myEMap.Clear();
133   myFMap.Clear();
134 }
135
136 //=======================================================================
137 //function : Index
138 //purpose  :
139 //=======================================================================
140 Standard_Integer HLRBRep_PolyAlgo::Index (const TopoDS_Shape& theShape) const
141 {
142   Standard_Integer i = 1;
143   for (TopTools_SequenceOfShape::Iterator aShapeIter (myShapes); aShapeIter.More(); aShapeIter.Next(), ++i)
144   {
145     if (aShapeIter.Value() == theShape)
146     {
147       return i;
148     }
149   }
150   return 0;
151 }
152
153 //=======================================================================
154 //function : Update
155 //purpose  :
156 //=======================================================================
157 void HLRBRep_PolyAlgo::Update()
158 {
159   myAlgo->Clear();
160   myEMap.Clear();
161   myFMap.Clear();
162
163   const TopoDS_Shape aShape = MakeShape();
164   if (aShape.IsNull())
165   {
166     return;
167   }
168
169   Standard_Boolean isIsoledF = false, isIsoledE = false;
170   const Standard_Integer aNbShell = InitShape (aShape, isIsoledF, isIsoledE);
171   if (aNbShell <= 0)
172   {
173     return;
174   }
175
176   TopExp::MapShapes (aShape, TopAbs_EDGE, myEMap);
177   TopExp::MapShapes (aShape, TopAbs_FACE, myFMap);
178   const Standard_Integer aNbEdge = myEMap.Extent();
179   const Standard_Integer aNbFace = myFMap.Extent();
180   TColStd_Array1OfInteger   anES (0, aNbEdge); // index of the Shell
181   NCollection_Array1<Handle(HLRAlgo_PolyData)> aPD (0, aNbFace);
182   NCollection_Array1<Handle(HLRAlgo_PolyInternalData)> aPID (0, aNbFace);
183   TopTools_MapOfShape aShapeMap1, aShapeMap2;
184   NCollection_Array1<Handle(HLRAlgo_PolyShellData)>& aShell = myAlgo->ChangePolyShell();
185   Standard_Integer iShell = 0;
186   for (TopExp_Explorer aShellIter (aShape, TopAbs_SHELL); aShellIter.More(); aShellIter.Next())
187   {
188     StoreShell (aShellIter.Current(), iShell, aShell,
189                 Standard_False, Standard_False,
190                 anES, aPD, aPID, aShapeMap1, aShapeMap2);
191   }
192   if (isIsoledF)
193   {
194     StoreShell (aShape, iShell, aShell, isIsoledF, Standard_False,
195                 anES, aPD, aPID, aShapeMap1, aShapeMap2);
196   }
197   if (isIsoledE)
198   {
199     StoreShell (aShape, iShell, aShell, Standard_False, isIsoledE,
200                 anES, aPD, aPID, aShapeMap1, aShapeMap2);
201   }
202   myAlgo->Update();
203 }
204
205 //=======================================================================
206 //function : MakeShape
207 //purpose  :
208 //=======================================================================
209 TopoDS_Shape HLRBRep_PolyAlgo::MakeShape() const
210 {
211   if (myShapes.IsEmpty())
212   {
213     return TopoDS_Shape();
214   }
215
216   BRep_Builder aBuilder;
217   TopoDS_Shape aComp;
218   aBuilder.MakeCompound (TopoDS::Compound (aComp));
219   for (TopTools_SequenceOfShape::Iterator aShapeIter (myShapes); aShapeIter.More(); aShapeIter.Next())
220   {
221     aBuilder.Add (aComp, aShapeIter.Value());
222   }
223   return aComp;
224 }
225
226 //=======================================================================
227 //function : InitShape
228 //purpose  :
229 //=======================================================================
230 Standard_Integer HLRBRep_PolyAlgo::InitShape (const TopoDS_Shape& theShape,
231                                               Standard_Boolean& theIsoledF,
232                                               Standard_Boolean& theIsoledE)
233 {
234   TopTools_MapOfShape aShapeMap0;
235   Standard_Integer aNbShell = 0;
236   theIsoledF = Standard_False;
237   theIsoledE = Standard_False;
238   TopExp_Explorer aFaceIter;
239   TopLoc_Location aLoc;
240
241   for (TopExp_Explorer aShellIter (theShape, TopAbs_SHELL); aShellIter.More(); aShellIter.Next())
242   {
243     Standard_Boolean hasTrian = Standard_False;
244     for (aFaceIter.Init (aShellIter.Current(), TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
245     {
246       const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
247       if (!BRep_Tool::Triangulation (aFace, aLoc).IsNull())
248       {
249         if (aShapeMap0.Add (aFace))
250         {
251           hasTrian = Standard_True;
252         }
253       }
254     }
255     if (hasTrian)
256     {
257       ++aNbShell;
258     }
259   }
260
261   for (aFaceIter.Init (theShape, TopAbs_FACE, TopAbs_SHELL); aFaceIter.More() && !theIsoledF; aFaceIter.Next())
262   {
263     const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
264     if (!BRep_Tool::Triangulation (aFace, aLoc).IsNull())
265     {
266       if (aShapeMap0.Add (aFace))
267       {
268         theIsoledF = Standard_True;
269       }
270     }
271   }
272   if (theIsoledF)
273   {
274     ++aNbShell;
275   }
276
277   for (TopExp_Explorer anEdgeIter (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More() && !theIsoledE; anEdgeIter.Next())
278   {
279     theIsoledE = Standard_True;
280   }
281   if (theIsoledE)
282   {
283     ++aNbShell;
284   }
285   if (aNbShell > 0)
286   {
287     myAlgo->Init (aNbShell);
288   }
289   return aNbShell;
290 }
291
292 //=======================================================================
293 //function : StoreShell
294 //purpose  :
295 //=======================================================================
296 void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& theShape,
297                                    Standard_Integer& theIShell,
298                                    NCollection_Array1<Handle(HLRAlgo_PolyShellData)>& theShell,
299                                    const Standard_Boolean theIsoledF,
300                                    const Standard_Boolean theIsoledE,
301                                    TColStd_Array1OfInteger& theES,
302                                    NCollection_Array1<Handle(HLRAlgo_PolyData)>& thePD,
303                                    NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID,
304                                    TopTools_MapOfShape& theShapeMap1,
305                                    TopTools_MapOfShape& theShapeMap2)
306 {
307   TopLoc_Location aLoc;
308   TopExp_Explorer aFaceExp, anEdgeExp;
309   Standard_Integer aNbFaceShell = 0;
310   Standard_Boolean isClosed = Standard_False;
311   const gp_Trsf& aProjTrsf = myProj.Transformation();
312   {
313     const gp_XYZ& aTrsfVec = aProjTrsf.TranslationPart();
314     TLoc[0] = aTrsfVec.X();
315     TLoc[1] = aTrsfVec.Y();
316     TLoc[2] = aTrsfVec.Z();
317
318     const gp_Mat& aTrsfMat = aProjTrsf.VectorialPart();
319     TMat[0][0] = aTrsfMat.Value (1, 1);
320     TMat[0][1] = aTrsfMat.Value (1, 2);
321     TMat[0][2] = aTrsfMat.Value (1, 3);
322     TMat[1][0] = aTrsfMat.Value (2, 1);
323     TMat[1][1] = aTrsfMat.Value (2, 2);
324     TMat[1][2] = aTrsfMat.Value (2, 3);
325     TMat[2][0] = aTrsfMat.Value (3, 1);
326     TMat[2][1] = aTrsfMat.Value (3, 2);
327     TMat[2][2] = aTrsfMat.Value (3, 3);
328   }
329   {
330     const gp_Trsf& aTrsfInv   = myProj.InvertedTransformation();
331     const gp_XYZ& aTrsfInvVec = aTrsfInv.TranslationPart();
332     TILo[0] = aTrsfInvVec.X();
333     TILo[1] = aTrsfInvVec.Y();
334     TILo[2] = aTrsfInvVec.Z();
335
336     const gp_Mat& aTrsfInvMat = aTrsfInv.VectorialPart();
337     TIMa[0][0] = aTrsfInvMat.Value (1, 1);
338     TIMa[0][1] = aTrsfInvMat.Value (1, 2);
339     TIMa[0][2] = aTrsfInvMat.Value (1, 3);
340     TIMa[1][0] = aTrsfInvMat.Value (2, 1);
341     TIMa[1][1] = aTrsfInvMat.Value (2, 2);
342     TIMa[1][2] = aTrsfInvMat.Value (2, 3);
343     TIMa[2][0] = aTrsfInvMat.Value (3, 1);
344     TIMa[2][1] = aTrsfInvMat.Value (3, 2);
345     TIMa[2][2] = aTrsfInvMat.Value (3, 3);
346   }
347   if (!theIsoledE)
348   {
349     if (!theIsoledF)
350     {
351       isClosed = theShape.Closed();
352       if (!isClosed)
353       {
354         TopTools_IndexedMapOfShape anEM;
355         TopExp::MapShapes (theShape, TopAbs_EDGE, anEM);
356         const Standard_Integer aNbEdge = anEM.Extent();
357         NCollection_Array1<Standard_Integer> aFlagArray (1, Max(aNbEdge, 1));
358         aFlagArray.Init (0);
359         for (anEdgeExp.Init (theShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next())
360         {
361           const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeExp.Current());
362           const Standard_Integer anEdgeIndex = anEM.FindIndex (anEdge);
363           TopAbs_Orientation anEdgeOrient = anEdge.Orientation();
364           if (!BRep_Tool::Degenerated (anEdge))
365           {
366             if      (anEdgeOrient == TopAbs_FORWARD ) { aFlagArray[anEdgeIndex] += 1; }
367             else if (anEdgeOrient == TopAbs_REVERSED) { aFlagArray[anEdgeIndex] -= 1; }
368           }
369         }
370         isClosed = Standard_True;
371         
372         for (Standard_Integer anEdgeIter = 1; anEdgeIter <= aNbEdge && isClosed; ++anEdgeIter)
373         {
374           isClosed = (aFlagArray[anEdgeIter] == 0);
375         }
376       }
377       
378       aFaceExp.Init (theShape, TopAbs_FACE);
379     }
380     else
381     {
382       aFaceExp.Init (theShape, TopAbs_FACE, TopAbs_SHELL);
383     }
384     
385     for (; aFaceExp.More(); aFaceExp.Next())
386     {
387       const TopoDS_Face& aFace = TopoDS::Face (aFaceExp.Current());
388       if (!BRep_Tool::Triangulation (aFace, aLoc).IsNull())
389       {
390         if (theShapeMap1.Add (aFace))
391         {
392           ++aNbFaceShell;
393         }
394       }
395     }
396   }
397   if (aNbFaceShell > 0 || theIsoledE)
398   {
399     ++theIShell;
400     theShell.SetValue (theIShell, new HLRAlgo_PolyShellData (aNbFaceShell));
401   }
402
403   if (aNbFaceShell > 0)
404   {
405     const Handle(HLRAlgo_PolyShellData)& aPsd = theShell.ChangeValue (theIShell);
406     Standard_Integer iFace = 0;
407     if (!theIsoledF) { aFaceExp.Init (theShape, TopAbs_FACE); }
408     else             { aFaceExp.Init (theShape, TopAbs_FACE, TopAbs_SHELL); }
409     
410     for (; aFaceExp.More(); aFaceExp.Next())
411     {
412       const TopoDS_Face& aFace = TopoDS::Face (aFaceExp.Current());
413       const Handle(Poly_Triangulation)& aTr = BRep_Tool::Triangulation (aFace, aLoc);
414       if (!aTr.IsNull())
415       {
416         if (theShapeMap2.Add (aFace))
417         {
418           iFace++;
419           const Standard_Integer aFaceIndex = myFMap.FindIndex (aFace);
420           const bool isReversed = aFace.Orientation() == TopAbs_REVERSED;
421           gp_Trsf aTT = aLoc.Transformation();
422           aTT.PreMultiply (aProjTrsf);
423           {
424             const gp_XYZ& aTTrsfVec = aTT.TranslationPart();
425             TTLo[0] = aTTrsfVec.X();
426             TTLo[1] = aTTrsfVec.Y();
427             TTLo[2] = aTTrsfVec.Z();
428
429             const gp_Mat& aTTrsfMat = aTT.VectorialPart();
430             TTMa[0][0] = aTTrsfMat.Value (1, 1);
431             TTMa[0][1] = aTTrsfMat.Value (1, 2);
432             TTMa[0][2] = aTTrsfMat.Value (1, 3);
433             TTMa[1][0] = aTTrsfMat.Value (2, 1);
434             TTMa[1][1] = aTTrsfMat.Value (2, 2);
435             TTMa[1][2] = aTTrsfMat.Value (2, 3);
436             TTMa[2][0] = aTTrsfMat.Value (3, 1);
437             TTMa[2][1] = aTTrsfMat.Value (3, 2);
438             TTMa[2][2] = aTTrsfMat.Value (3, 3);
439           }
440           const Standard_Integer aNbNodes = aTr->NbNodes();
441           const Standard_Integer aNbTris  = aTr->NbTriangles();
442           thePD.SetValue  (aFaceIndex, new HLRAlgo_PolyData());
443           aPsd->PolyData().SetValue (iFace, thePD.Value (aFaceIndex));
444           thePID.SetValue (aFaceIndex, new HLRAlgo_PolyInternalData (aNbNodes, aNbTris));
445           const Handle(HLRAlgo_PolyInternalData)& aPid = thePID.ChangeValue (aFaceIndex);
446           if (Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace))
447           {
448             if (Handle(Geom_RectangularTrimmedSurface) aRectTrimSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf))
449             {
450               aSurf = aRectTrimSurf->BasisSurface();
451             }
452             GeomAdaptor_Surface aSurfAdapt (aSurf);
453             aPid->Planar (aSurfAdapt.GetType() == GeomAbs_Plane);
454           }
455           else
456           {
457             aPid->Planar (false);
458           }
459
460           HLRAlgo_Array1OfTData& aTData = aPid->TData();
461           HLRAlgo_Array1OfPISeg& aPISeg = aPid->PISeg();
462           HLRAlgo_Array1OfPINod& aPINod = aPid->PINod();
463           for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
464           {
465             const Poly_Triangle&  aPolyTri = aTr->Triangle (aTriIter);
466             HLRAlgo_TriangleData& aTriData = aTData.ChangeValue (aTriIter);
467             aTriData.Flags = 0;
468             if (isReversed)
469             {
470               aPolyTri.Get (aTriData.Node3, aTriData.Node2, aTriData.Node1);
471             }
472             else
473             {
474               aPolyTri.Get (aTriData.Node1, aTriData.Node2, aTriData.Node3);
475             }
476           }
477
478           for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
479           {
480             const gp_Pnt& aPnt = aTr->Node (aNodeIter);
481             const Handle(HLRAlgo_PolyInternalNode)& aPolyINode   = aPINod.ChangeValue (aNodeIter);
482             HLRAlgo_PolyInternalNode::NodeData&     aNod1RValues = aPolyINode->Data();
483             HLRAlgo_PolyInternalNode::NodeIndices&  aNodIndices  = aPolyINode->Indices();
484             aNodIndices.NdSg = 0;
485             aNodIndices.Flag = 0;
486             aNod1RValues.Point = aPnt.XYZ();
487             TTMultiply (aNod1RValues.Point);
488           }
489           aPid->UpdateLinks (aTData, aPISeg, aPINod);
490           if (aTr->HasUVNodes())
491           {
492             const bool hasSurf = BRep_Tool::IsGeometric (aFace);
493             myBSurf.Initialize (aFace, Standard_False);
494             for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
495             {
496               const Handle(HLRAlgo_PolyInternalNode)& aPolyINode   = aPINod.ChangeValue (aNodeIter);
497               HLRAlgo_PolyInternalNode::NodeIndices&  aNodIndices  = aPolyINode->Indices();
498               HLRAlgo_PolyInternalNode::NodeData&     aNod1RValues = aPolyINode->Data();
499               if (aTr->HasUVNodes())
500               {
501                 aNod1RValues.UV = aTr->UVNode (aNodeIter).XY();
502               }
503               if (aTr->HasNormals())
504               {
505                 aNod1RValues.Normal = aTr->Normal (aNodeIter).XYZ();
506               }
507
508               if ((aTr->HasNormals()
509               || (hasSurf && aTr->HasUVNodes()))
510               && Normal (aNodeIter, aNodIndices, aNod1RValues, aTData, aPISeg, aPINod, Standard_False))
511               {
512                 aNodIndices.Flag |=  NMsk_Norm;
513               }
514               else
515               {
516                 aNodIndices.Flag &= ~NMsk_Norm;
517                 aNod1RValues.Scal = 0;
518               }
519             }
520           }
521         #ifdef OCCT_DEBUG
522           else if (DoError)
523           {
524             std::cout << " HLRBRep_PolyAlgo::StoreShell : Face ";
525             std::cout << aFaceIndex << " non triangulated" << std::endl;
526           }
527         #endif
528
529           for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
530           {
531             HLRAlgo_TriangleData& aTriData = aTData.ChangeValue (aTriIter);
532             const Handle(HLRAlgo_PolyInternalNode)& aPN1 = aPINod.ChangeValue (aTriData.Node1);
533             const Handle(HLRAlgo_PolyInternalNode)& aPN2 = aPINod.ChangeValue (aTriData.Node2);
534             const Handle(HLRAlgo_PolyInternalNode)& aPN3 = aPINod.ChangeValue (aTriData.Node3);
535             OrientTriangle (aTriIter, aTriData,
536                             aPN1->Indices(), aPN1->Data(),
537                             aPN2->Indices(), aPN2->Data(),
538                             aPN3->Indices(), aPN3->Data());
539           }
540         }
541       }
542 #ifdef OCCT_DEBUG
543       else if (DoError)
544       {
545         std::cout << "HLRBRep_PolyAlgo::StoreShell : Face ";
546         std::cout << iFace << " deja stockee" << std::endl;
547       }
548 #endif
549     }
550
551     const Standard_Integer aNbFaces = myFMap.Extent();
552     HLRAlgo_ListOfBPoint& aList = aPsd->Edges();
553     TopTools_IndexedDataMapOfShapeListOfShape EF;
554     TopExp::MapShapesAndAncestors (theShape, TopAbs_EDGE, TopAbs_FACE, EF);
555     for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
556     {
557       if (!thePID.Value (aFaceIter).IsNull())
558       {
559         for (anEdgeExp.Init (myFMap (aFaceIter), TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next())
560         {
561           TopoDS_Edge anEdge = TopoDS::Edge (anEdgeExp.Current());
562           if (theShapeMap1.Add (anEdge))
563           {
564             Standard_Integer anEdgeIndex = myEMap.FindIndex (anEdge);
565             theES.SetValue (anEdgeIndex, theIShell);
566             Standard_Integer anIndexE = EF.FindIndex (anEdge);
567             if (anIndexE > 0)
568             {
569               TopTools_ListOfShape& LS = EF (anIndexE);
570               InitBiPointsWithConnexity (anEdgeIndex, anEdge, aList, thePID, LS, Standard_True);
571             }
572             else
573             {
574               TopTools_ListOfShape LS;
575               InitBiPointsWithConnexity (anEdgeIndex, anEdge, aList, thePID, LS, Standard_False);
576             }
577           }
578         }
579       }
580     }
581     InsertOnOutLine (thePID);
582     CheckFrBackTriangles (aList, thePID);
583     UpdateOutLines (aList, thePID);
584     UpdateEdgesBiPoints (aList, thePID, isClosed);
585     UpdatePolyData (thePD, thePID, isClosed);
586
587     for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
588     {
589       thePID.ChangeValue (aFaceIter).Nullify();
590     }
591   }
592   else if (theIsoledE)
593   {
594     const Handle(HLRAlgo_PolyShellData)& aPsd = theShell.ChangeValue (theIShell);
595     HLRAlgo_ListOfBPoint& aList = aPsd->Edges();
596     for (anEdgeExp.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeExp.More(); anEdgeExp.Next())
597     {
598       TopoDS_Edge anEdge = TopoDS::Edge (anEdgeExp.Current());
599       if (theShapeMap1.Add (anEdge))
600       {
601         Standard_Integer anEdgeIndex = myEMap.FindIndex (anEdge);
602         theES.SetValue (anEdgeIndex, theIShell);
603         TopTools_ListOfShape aLS;
604         InitBiPointsWithConnexity (anEdgeIndex, anEdge, aList, thePID, aLS, Standard_False);
605       }
606     }
607   }
608 }
609
610 //=======================================================================
611 //function : Normal
612 //purpose  :
613 //=======================================================================
614 Standard_Boolean HLRBRep_PolyAlgo::Normal (const Standard_Integer theNodeIndex,
615                                            HLRAlgo_PolyInternalNode::NodeIndices& theNodIndices,
616                                            HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
617                                            HLRAlgo_Array1OfTData& theTriData,
618                                            HLRAlgo_Array1OfPISeg& thePISeg,
619                                            HLRAlgo_Array1OfPINod& thePINod,
620                                            const Standard_Boolean theToOrient) const
621 {
622   if (theNod1RValues.Normal.SquareModulus() < Precision::Confusion())
623   {
624     gp_Vec aD1U, aD1V;
625     gp_Pnt aPnt;
626     CSLib_DerivativeStatus aStatus = CSLib_D1IsNull;
627     myBSurf.D1 (theNod1RValues.UV.X(), theNod1RValues.UV.Y(), aPnt, aD1U, aD1V);
628     gp_Dir aNorm;
629     CSLib::Normal (aD1U, aD1V, Precision::Angular(), aStatus, aNorm);
630     if (aStatus != CSLib_Done)
631     {
632       gp_Vec aD2U, aD2V, aD2UV;
633       bool isOK = false;
634       CSLib_NormalStatus aNromStatus;
635       myBSurf.D2 (theNod1RValues.UV.X(), theNod1RValues.UV.Y(), aPnt, aD1U, aD1V, aD2U, aD2V, aD2UV);
636       CSLib::Normal (aD1U, aD1V, aD2U, aD2V, aD2UV,
637                      Precision::Angular(), isOK, aNromStatus, aNorm);
638       if (!isOK)
639       {
640         return false;
641       }
642     }
643     theNod1RValues.Normal = aNorm.XYZ();
644   }
645
646   TMultiply (theNod1RValues.Normal, myProj.Perspective());
647
648   gp_XYZ anAverNorm;
649   if (AverageNormal (theNodeIndex, theNodIndices, theTriData, thePISeg, thePINod, anAverNorm))
650   {
651     if (theNod1RValues.Normal * anAverNorm < 0)
652     {
653       theNod1RValues.Normal.Reverse();
654     }
655
656     gp_XYZ anEyeDir (0.0, 0.0, -1.0);
657     if (myProj.Perspective())
658     {
659       anEyeDir.SetCoord (theNod1RValues.Point.X(),
660                          theNod1RValues.Point.Y(),
661                          theNod1RValues.Point.Z() - myProj.Focus());
662       const Standard_Real anEyeMod = anEyeDir.Modulus();
663       if (anEyeMod > 0.0)
664       {
665         anEyeDir /= anEyeMod;
666       }
667     }
668     theNod1RValues.Scal = (theNod1RValues.Normal * anEyeDir);
669   }
670   else
671   {
672     theNod1RValues.Scal = 0;
673     theNod1RValues.Normal = gp_XYZ(1., 0., 0.);
674 #ifdef OCCT_DEBUG
675     if (DoError) {
676       std::cout << "HLRBRep_PolyAlgo::Normal : AverageNormal error";
677       std::cout << std::endl;
678     }
679 #endif
680   }
681   if (theNod1RValues.Scal > 0)
682   {
683     if ( theNod1RValues.Scal < myTolAngular)
684     {
685       theNod1RValues.Scal  = 0;
686       theNodIndices.Flag |= NMsk_OutL;
687     }
688   }
689   else
690   {
691     if (-theNod1RValues.Scal < myTolAngular)
692     {
693       theNod1RValues.Scal  = 0;
694       theNodIndices.Flag |= NMsk_OutL;
695     }
696   }
697
698   if (theToOrient)
699   {
700     UpdateAroundNode (theNodeIndex, theNodIndices, theTriData, thePISeg, thePINod);
701   }
702   return Standard_True;
703 }
704
705 //=======================================================================
706 //function : AverageNormal
707 //purpose  :
708 //=======================================================================
709 Standard_Boolean HLRBRep_PolyAlgo::AverageNormal (const Standard_Integer iNode,
710                                                   HLRAlgo_PolyInternalNode::NodeIndices& theNodeIndices,
711                                                   HLRAlgo_Array1OfTData& theTData,
712                                                   HLRAlgo_Array1OfPISeg& thePISeg,
713                                                   HLRAlgo_Array1OfPINod& thePINod,
714                                                   Standard_Real& theX,
715                                                   Standard_Real& theY,
716                                                   Standard_Real& theZ) const
717 {
718   Standard_Boolean isOK = Standard_False;
719   Standard_Integer jNode = 0, kNode, iiii;
720   theX = 0;
721   theY = 0;
722   theZ = 0;
723   iiii = theNodeIndices.NdSg;
724   while (iiii != 0 && !isOK)
725   {
726     HLRAlgo_PolyInternalSegment& aSegIndices = thePISeg.ChangeValue (iiii);
727     const Standard_Integer iTri1 = aSegIndices.Conex1;
728     const Standard_Integer iTri2 = aSegIndices.Conex2;
729     if (iTri1 != 0) { AddNormalOnTriangle (iTri1, iNode, jNode, theTData, thePINod, theX, theY, theZ, isOK); }
730     if (iTri2 != 0) { AddNormalOnTriangle (iTri2, iNode, jNode, theTData, thePINod, theX, theY, theZ, isOK); }
731     if (aSegIndices.LstSg1 == iNode) { iiii = aSegIndices.NxtSg1; }
732     else                             { iiii = aSegIndices.NxtSg2; }
733   }
734
735   if (jNode != 0)
736   {
737     iiii = theNodeIndices.NdSg;
738     
739     while (iiii != 0 && !isOK)
740     {
741       HLRAlgo_PolyInternalSegment& aSegIndices = thePISeg.ChangeValue(iiii);
742       const Standard_Integer iTri1 = aSegIndices.Conex1;
743       const Standard_Integer iTri2 = aSegIndices.Conex2;
744       if (iTri1 != 0) { AddNormalOnTriangle (iTri1, jNode, kNode, theTData, thePINod, theX, theY, theZ, isOK); }
745       if (iTri2 != 0) { AddNormalOnTriangle (iTri2, jNode, kNode, theTData, thePINod, theX, theY, theZ, isOK); }
746       if (aSegIndices.LstSg1 == jNode) { iiii = aSegIndices.NxtSg1; }
747       else                             { iiii = aSegIndices.NxtSg2; }
748     }
749   }
750   const Standard_Real aD = sqrt (theX * theX + theY * theY + theZ * theZ);
751   if (isOK && aD < 1.e-10)
752   {
753     isOK = Standard_False;
754 #ifdef OCCT_DEBUG
755     if (DoError)
756     {
757       std::cout << "HLRAlgo_PolyInternalData:: inverted normals on ";
758       std::cout << "node " << iNode << std::endl;
759     }
760 #endif
761   }
762   return isOK;
763 }
764
765 //=======================================================================
766 //function : AddNormalOnTriangle
767 //purpose  :
768 //=======================================================================
769 void HLRBRep_PolyAlgo::AddNormalOnTriangle (const Standard_Integer theITri,
770                                             const Standard_Integer theINode,
771                                             Standard_Integer& theJNode,
772                                             HLRAlgo_Array1OfTData& theTData,
773                                             HLRAlgo_Array1OfPINod& thePINod,
774                                             Standard_Real& theX,
775                                             Standard_Real& theY,
776                                             Standard_Real& theZ,
777                                             Standard_Boolean& theIsOK) const
778 {
779   const HLRAlgo_TriangleData& aTriangle = theTData.Value (theITri);
780   const HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = thePINod.Value (aTriangle.Node1)->Data();
781   const HLRAlgo_PolyInternalNode::NodeData& aNod2RValues = thePINod.Value (aTriangle.Node2)->Data();
782   const HLRAlgo_PolyInternalNode::NodeData& aNod3RValues = thePINod.Value (aTriangle.Node3)->Data();
783   const gp_XYZ aD1 = aNod2RValues.Point - aNod1RValues.Point;
784   const Standard_Real aD1Norm = aD1.Modulus();
785   if (aD1Norm < 1.e-10)
786   {
787     if      (aTriangle.Node1 == theINode) { theJNode = aTriangle.Node2; }
788     else if (aTriangle.Node2 == theINode) { theJNode = aTriangle.Node1; }
789   }
790   else
791   {
792     const gp_XYZ aD2 = aNod3RValues.Point - aNod2RValues.Point;
793     const Standard_Real aD2Norm = aD2.Modulus();
794     if (aD2Norm < 1.e-10)
795     {
796       if      (aTriangle.Node2 == theINode) { theJNode = aTriangle.Node3; }
797       else if (aTriangle.Node3 == theINode) { theJNode = aTriangle.Node2; }
798     }
799     else
800     {
801       const gp_XYZ aD3 = aNod1RValues.Point - aNod3RValues.Point;
802       const Standard_Real aD3Norm = aD3.Modulus();
803       if (aD3Norm < 1.e-10)
804       {
805         if      (aTriangle.Node3 == theINode) { theJNode = aTriangle.Node1; }
806         else if (aTriangle.Node1 == theINode) { theJNode = aTriangle.Node3; }
807       }
808       else
809       {
810         const gp_XYZ aDN = (1 / (aD1Norm * aD2Norm)) * (aD1 ^ aD2);
811         const Standard_Real aDNNorm = aDN.Modulus();
812         if (aDNNorm > 1.e-10)
813         {
814           theIsOK = Standard_True;
815           theX += aDN.X();
816           theY += aDN.Y();
817           theZ += aDN.Z();
818         }
819       }
820     }
821   }
822 }
823
824 //=======================================================================
825 //function : InitBiPointsWithConnexity
826 //purpose  :
827 //=======================================================================
828 void HLRBRep_PolyAlgo::InitBiPointsWithConnexity (const Standard_Integer theIEdge,
829                                                   TopoDS_Edge& theEdge,
830                                                   HLRAlgo_ListOfBPoint& theList,
831                                                   NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID,
832                                                   TopTools_ListOfShape& theLS,
833                                                   const Standard_Boolean theIsConnex)
834 {
835   Standard_Real X1  , Y1  , Z1  , X2  , Y2  , Z2  ;
836   Standard_Real XTI1, YTI1, ZTI1, XTI2, YTI2, ZTI2;
837   Standard_Real U1 = 0.0, U2 = 0.0;
838   Handle(Poly_PolygonOnTriangulation) aHPol[2];
839   TopLoc_Location aLoc;
840   myBCurv.Initialize (theEdge);
841   if (theIsConnex)
842   {
843     const Standard_Integer aNbConnex = theLS.Extent();
844     if (aNbConnex == 1)
845     {
846       TopTools_ListIteratorOfListOfShape itn (theLS);
847       const TopoDS_Face& aF1 = TopoDS::Face (itn.Value());
848       const Standard_Integer i1 = myFMap.FindIndex (aF1);
849       const Handle(Poly_Triangulation)& aTr1 = BRep_Tool::Triangulation (aF1, aLoc);
850       aHPol[0] = BRep_Tool::PolygonOnTriangulation (theEdge, aTr1, aLoc);
851       const Handle(HLRAlgo_PolyInternalData)& pid1 = thePID.Value (i1);
852       if (!aHPol[0].IsNull())
853       {
854         myPC.Initialize (theEdge, aF1);
855         const Handle(TColStd_HArray1OfReal)& par = aHPol[0]->Parameters();
856         const TColStd_Array1OfInteger&     aPol1 = aHPol[0]->Nodes();
857         const Standard_Integer aNbPol  = aPol1.Upper();
858         HLRAlgo_Array1OfTData* aTData1 = &pid1->TData();
859         HLRAlgo_Array1OfPISeg* aPISeg1 = &pid1->PISeg();
860         HLRAlgo_Array1OfPINod* aPINod1 = &pid1->PINod();
861         const Handle(HLRAlgo_PolyInternalNode)& pi1p1 = aPINod1->ChangeValue (aPol1 (1    ));
862         HLRAlgo_PolyInternalNode::NodeIndices*  aNode11Indices = &pi1p1->Indices();
863         HLRAlgo_PolyInternalNode::NodeData*     aNod11RValues  = &pi1p1->Data();
864         const Handle(HLRAlgo_PolyInternalNode)& pi1p2 = aPINod1->ChangeValue (aPol1 (aNbPol));
865         HLRAlgo_PolyInternalNode::NodeIndices*  aNode12Indices = &pi1p2->Indices();
866         HLRAlgo_PolyInternalNode::NodeData*     aNod12RValues  = &pi1p2->Data();
867         aNode11Indices->Flag |=  NMsk_Vert;
868         aNode12Indices->Flag |=  NMsk_Vert;
869         
870         for (Standard_Integer iPol = 1; iPol <= aNbPol; iPol++)
871         {
872           const Handle(HLRAlgo_PolyInternalNode)& pi1pA = aPINod1->ChangeValue (aPol1 (iPol));
873           HLRAlgo_PolyInternalNode::NodeIndices& aNodeIndices1A = pi1pA->Indices();
874           HLRAlgo_PolyInternalNode::NodeData& Nod1ARValues = pi1pA->Data();
875           if (aNodeIndices1A.Edg1 == 0 || aNodeIndices1A.Edg1 == theIEdge)
876           {
877             aNodeIndices1A.Edg1 = theIEdge;
878             Nod1ARValues.PCu1 = par->Value (iPol);
879           }
880           else
881           {
882             aNodeIndices1A.Edg2 = theIEdge;
883             Nod1ARValues.PCu2 = par->Value (iPol);
884           }
885         }
886         
887         Standard_Integer i1p2 = aPol1 (1);
888         aNode12Indices = aNode11Indices;
889         aNod12RValues  = aNod11RValues;
890         XTI2 = X2 = aNod12RValues->Point.X();
891         YTI2 = Y2 = aNod12RValues->Point.Y();
892         ZTI2 = Z2 = aNod12RValues->Point.Z();
893         if      (aNode12Indices->Edg1 == theIEdge) { U2 = aNod12RValues->PCu1; }
894         else if (aNode12Indices->Edg2 == theIEdge) { U2 = aNod12RValues->PCu2; }
895       #ifdef OCCT_DEBUG
896         else
897         {
898           std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
899           std::cout << "Parameter error on Node " << i1p2 << std::endl;
900         }
901       #endif
902         aNode12Indices->Flag |= NMsk_Edge;
903         TIMultiply (XTI2, YTI2, ZTI2);
904         if (aPol1 (1) == aPol1 (aNbPol)
905          && myPC.IsPeriodic())
906         {
907           U2 = U2 - myPC.Period();
908         }
909         
910         if (aNbPol == 2 && BRep_Tool::Degenerated (theEdge))
911         {
912           CheckDegeneratedSegment (*aNode11Indices, *aNod11RValues,
913                                    *aNode12Indices, *aNod12RValues);
914           UpdateAroundNode (aPol1 (1     ), *aNode11Indices, *aTData1, *aPISeg1, *aPINod1);
915           UpdateAroundNode (aPol1 (aNbPol), *aNode12Indices, *aTData1, *aPISeg1, *aPINod1);
916         }
917         else
918         {
919           for (Standard_Integer iPol = 2; iPol <= aNbPol; iPol++)
920           {
921             const Standard_Integer i1p1 = i1p2;
922             aNode11Indices = aNode12Indices;
923             aNod11RValues  = aNod12RValues;
924             i1p2 = aPol1 (iPol);
925             const Handle(HLRAlgo_PolyInternalNode)& pi1p2iPol = aPINod1->ChangeValue (aPol1 (iPol));
926             aNode12Indices = &pi1p2iPol->Indices();
927             aNod12RValues  = &pi1p2iPol->Data();
928           #ifdef OCCT_DEBUG
929             if (DoError)
930             {
931               if (aNod11RValues->Normal.X() * aNod12RValues->Normal.X() +
932                   aNod11RValues->Normal.Y() * aNod12RValues->Normal.Y() +
933                   aNod11RValues->Normal.Z() * aNod12RValues->Normal.Z() < 0)
934               {
935                 std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
936                 std::cout << "Too big angle between " << i1p1 << std::setw(6);
937                 std::cout << " and " << i1p2 << std::setw(6);
938                 std::cout << " in face " << i1 << std::endl;
939               }
940             }
941           #endif
942             X1   = X2;
943             Y1   = Y2;
944             Z1   = Z2;
945             XTI1 = XTI2;
946             YTI1 = YTI2;
947             ZTI1 = ZTI2;
948             U1   = U2;
949             XTI2 = X2 = aNod12RValues->Point.X();
950             YTI2 = Y2 = aNod12RValues->Point.Y();
951             ZTI2 = Z2 = aNod12RValues->Point.Z();
952             if      (aNode12Indices->Edg1 == theIEdge) { U2 = aNod12RValues->PCu1; }
953             else if (aNode12Indices->Edg2 == theIEdge) { U2 = aNod12RValues->PCu2; }
954           #ifdef OCCT_DEBUG
955             else
956             {
957               std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
958               std::cout << "Parameter error on Node " << i1p2 << std::endl;
959             }
960           #endif
961             aNode12Indices->Flag |= NMsk_Edge;
962             TIMultiply (XTI2, YTI2, ZTI2);
963             Interpolation (theList,
964                            X1  , Y1  , Z1  , X2  , Y2  , Z2  ,
965                            XTI1, YTI1, ZTI1, XTI2, YTI2, ZTI2,
966                            theIEdge, U1, U2,
967                            *aNode11Indices, *aNod11RValues,
968                            *aNode12Indices, *aNod12RValues,
969                            i1p1, i1p2, i1, pid1, aTData1, aPISeg1, aPINod1);
970           }
971         }
972       }
973     #ifdef OCCT_DEBUG
974       else if (DoError)
975       {
976         std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
977         std::cout << theIEdge << " connex 1 sans PolygonOnTriangulation" << std::endl;
978       }
979     #endif
980     }
981     else if (aNbConnex == 2)
982     {
983       TopTools_ListIteratorOfListOfShape itn (theLS);
984       const TopoDS_Face&     aF1 = TopoDS::Face (itn.Value());
985       const Standard_Integer i1  = myFMap.FindIndex (aF1);
986       const Handle(Poly_Triangulation)& aTr1 = BRep_Tool::Triangulation (aF1, aLoc);
987       aHPol[0] = BRep_Tool::PolygonOnTriangulation (theEdge, aTr1, aLoc);
988       itn.Next();
989       const TopoDS_Face&     aF2 = TopoDS::Face (itn.Value());
990       const Standard_Integer i2  = myFMap.FindIndex (aF2);
991       if (i1 == i2) { theEdge.Reverse(); }
992       const Handle(Poly_Triangulation)& aTr2 = BRep_Tool::Triangulation (aF2, aLoc);
993       aHPol[1] = BRep_Tool::PolygonOnTriangulation (theEdge, aTr2, aLoc);
994       GeomAbs_Shape rg = BRep_Tool::Continuity (theEdge, aF1, aF2);
995       const Handle(HLRAlgo_PolyInternalData)& pid1 = thePID.Value (i1);
996       const Handle(HLRAlgo_PolyInternalData)& pid2 = thePID.Value (i2);
997       if (!aHPol[0].IsNull()
998        && !aHPol[1].IsNull())
999       {
1000         myPC.Initialize (theEdge, aF1);
1001         const TColStd_Array1OfInteger&      aPol1 = aHPol[0]->Nodes();
1002         const TColStd_Array1OfInteger&      aPol2 = aHPol[1]->Nodes();
1003         const Handle(TColStd_HArray1OfReal)& par = aHPol[0]->Parameters();
1004         const Standard_Integer aNbPol1 = aPol1.Upper();
1005         HLRAlgo_Array1OfTData* aTData1 = &pid1->TData();
1006         HLRAlgo_Array1OfPISeg* aPISeg1 = &pid1->PISeg();
1007         HLRAlgo_Array1OfPINod* aPINod1 = &pid1->PINod();
1008         HLRAlgo_Array1OfTData* aTData2 = &pid2->TData();
1009         HLRAlgo_Array1OfPISeg* aPISeg2 = &pid2->PISeg();
1010         HLRAlgo_Array1OfPINod* aPINod2 = &pid2->PINod();
1011         const Handle(HLRAlgo_PolyInternalNode)* pi1p1 = &aPINod1->ChangeValue (aPol1 (1));
1012         HLRAlgo_PolyInternalNode::NodeIndices*  aNode11Indices = &(*pi1p1)->Indices();
1013         HLRAlgo_PolyInternalNode::NodeData*     aNod11RValues  = &(*pi1p1)->Data();
1014         const Handle(HLRAlgo_PolyInternalNode)* pi1p2nbPol1 = &aPINod1->ChangeValue (aPol1 (aNbPol1));
1015         HLRAlgo_PolyInternalNode::NodeIndices*  aNode12Indices = &(*pi1p2nbPol1)->Indices();
1016         HLRAlgo_PolyInternalNode::NodeData*     aNod12RValues  = &(*pi1p2nbPol1)->Data();
1017         const Handle(HLRAlgo_PolyInternalNode)* pi2p1 = &aPINod2->ChangeValue (aPol2 (1));
1018         HLRAlgo_PolyInternalNode::NodeIndices*  aNod21Indices = &(*pi2p1)->Indices();
1019         HLRAlgo_PolyInternalNode::NodeData*     aNod21RValues = &(*pi2p1)->Data();
1020         const Handle(HLRAlgo_PolyInternalNode)* pi2p2 = &aPINod2->ChangeValue (aPol2 (aNbPol1));
1021         HLRAlgo_PolyInternalNode::NodeIndices*  aNod22Indices = &(*pi2p2)->Indices();
1022         HLRAlgo_PolyInternalNode::NodeData*     aNod22RValues = &(*pi2p2)->Data();
1023         aNode11Indices->Flag |=  NMsk_Vert;
1024         aNode12Indices->Flag |=  NMsk_Vert;
1025         aNod21Indices->Flag |=  NMsk_Vert;
1026         aNod22Indices->Flag |=  NMsk_Vert;
1027         
1028         for (Standard_Integer iPol = 1; iPol <= aNbPol1; iPol++)
1029         {
1030           const Handle(HLRAlgo_PolyInternalNode)* pi1pA = &aPINod1->ChangeValue (aPol1 (iPol));
1031           HLRAlgo_PolyInternalNode::NodeIndices*  aNod1AIndices = &(*pi1pA)->Indices();
1032           HLRAlgo_PolyInternalNode::NodeData*     aNod1ARValues = &(*pi1pA)->Data();
1033           const Handle(HLRAlgo_PolyInternalNode)* pi2pA = &aPINod2->ChangeValue (aPol2 (iPol));
1034           HLRAlgo_PolyInternalNode::NodeIndices*  aNod2AIndices = &(*pi2pA)->Indices();
1035           HLRAlgo_PolyInternalNode::NodeData*     aNod2ARValues = &(*pi2pA)->Data();
1036           Standard_Real PCu = par->Value(iPol);
1037           if (aNod1AIndices->Edg1 == 0 || aNod1AIndices->Edg1 == theIEdge)
1038           {
1039             aNod1AIndices->Edg1 = theIEdge;
1040             aNod1ARValues->PCu1 = PCu;
1041           }
1042           else
1043           {
1044             aNod1AIndices->Edg2 = theIEdge;
1045             aNod1ARValues->PCu2 = PCu;
1046           }
1047           if (aNod2AIndices->Edg1 == 0 || aNod2AIndices->Edg1 == theIEdge)
1048           {
1049             aNod2AIndices->Edg1 = theIEdge;
1050             aNod2ARValues->PCu1 = PCu;
1051           }
1052           else
1053           {
1054             aNod2AIndices->Edg2 = theIEdge;
1055             aNod2ARValues->PCu2 = PCu;
1056           }
1057         }
1058
1059         Standard_Integer i1p2 = aPol1 (1);
1060         aNode12Indices = aNode11Indices;
1061         aNod12RValues  = aNod11RValues;
1062         Standard_Integer i2p2 = aPol2 (1);
1063         aNod22Indices = aNod21Indices;
1064         aNod22RValues = aNod21RValues;
1065         XTI2 = X2 = aNod12RValues->Point.X();
1066         YTI2 = Y2 = aNod12RValues->Point.Y();
1067         ZTI2 = Z2 = aNod12RValues->Point.Z();
1068         if      (aNode12Indices->Edg1 == theIEdge) { U2 = aNod12RValues->PCu1; }
1069         else if (aNode12Indices->Edg2 == theIEdge) { U2 = aNod12RValues->PCu2; }
1070       #ifdef OCCT_DEBUG
1071         else
1072         {
1073           std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
1074           std::cout << "Parameter error on Node " << i1p2 << std::endl;
1075         }
1076       #endif
1077         aNode12Indices->Flag |= NMsk_Edge;
1078         aNod22Indices ->Flag |= NMsk_Edge;
1079         TIMultiply (XTI2, YTI2, ZTI2);
1080         if (aPol1 (1) == aPol1 (aNbPol1) && myPC.IsPeriodic())
1081         {
1082           U2 = U2 - myPC.Period();
1083         }
1084         
1085         if (aNbPol1 == 2 && BRep_Tool::Degenerated (theEdge))
1086         {
1087           CheckDegeneratedSegment (*aNode11Indices, *aNod11RValues,
1088                                    *aNode12Indices, *aNod12RValues);
1089           CheckDegeneratedSegment (*aNod21Indices,  *aNod21RValues,
1090                                    *aNod22Indices,  *aNod22RValues);
1091           UpdateAroundNode (aPol1 (1     ),  *aNode11Indices, *aTData1, *aPISeg1, *aPINod1);
1092           UpdateAroundNode (aPol1 (aNbPol1), *aNode12Indices, *aTData1, *aPISeg1, *aPINod1);
1093           UpdateAroundNode (aPol2 (1     ),  *aNod21Indices,  *aTData2, *aPISeg2, *aPINod2);
1094           UpdateAroundNode (aPol2 (aNbPol1), *aNod22Indices,  *aTData2, *aPISeg2, *aPINod2);
1095         }
1096         else
1097         {
1098           for (Standard_Integer iPol = 2; iPol <= aNbPol1; iPol++)
1099           {
1100             const Standard_Integer i1p1 = i1p2;
1101             aNode11Indices = aNode12Indices;
1102             aNod11RValues  = aNod12RValues;
1103             const Standard_Integer i2p1 = i2p2;
1104             aNod21Indices = aNod22Indices;
1105             aNod21RValues = aNod22RValues;
1106             i1p2 = aPol1 (iPol);
1107             const Handle(HLRAlgo_PolyInternalNode)* pi1p2iPol = &aPINod1->ChangeValue (aPol1 (iPol));
1108             aNode12Indices = &(*pi1p2iPol)->Indices();
1109             aNod12RValues  = &(*pi1p2iPol)->Data();
1110             i2p2 = aPol2 (iPol);
1111             const Handle(HLRAlgo_PolyInternalNode)* pi2p2iPol = &aPINod2->ChangeValue (aPol2 (iPol));
1112             aNod22Indices = &(*pi2p2iPol)->Indices();
1113             aNod22RValues = &(*pi2p2iPol)->Data();
1114           #ifdef OCCT_DEBUG
1115             if (DoError)
1116             {
1117               if (aNod11RValues->Normal.X() * aNod12RValues->Normal.X() +
1118                   aNod11RValues->Normal.Y() * aNod12RValues->Normal.Y() +
1119                   aNod11RValues->Normal.Z() * aNod12RValues->Normal.Z() < 0)
1120               {
1121                 std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
1122                 std::cout << "To big angle between " << i1p1 << std::setw(6);
1123                 std::cout << " and " << i1p2 << std::setw(6);
1124                 std::cout << " in face " << i1 << std::endl;
1125               }
1126               if (aNod21RValues->Normal.X() * aNod22RValues->Normal.X() +
1127                   aNod21RValues->Normal.Y() * aNod22RValues->Normal.Y() +
1128                   aNod21RValues->Normal.Z() * aNod22RValues->Normal.Z() < 0)
1129               {
1130                 std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
1131                 std::cout << "To big angle between " << i2p1 << std::setw(6);
1132                 std::cout << " and " << i2p2 << std::setw(6);
1133                 std::cout<< " in face " << i2 << std::endl;
1134               }
1135             }
1136           #endif
1137             X1   = X2;
1138             Y1   = Y2;
1139             Z1   = Z2;
1140             XTI1 = XTI2;
1141             YTI1 = YTI2;
1142             ZTI1 = ZTI2;
1143             U1   = U2;
1144             XTI2 = X2 = aNod12RValues->Point.X();
1145             YTI2 = Y2 = aNod12RValues->Point.Y();
1146             ZTI2 = Z2 = aNod12RValues->Point.Z();
1147             if      (aNode12Indices->Edg1 == theIEdge) { U2 = aNod12RValues->PCu1; }
1148             else if (aNode12Indices->Edg2 == theIEdge) { U2 = aNod12RValues->PCu2; }
1149           #ifdef OCCT_DEBUG
1150             else
1151             {
1152               std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
1153               std::cout << "Parameter error on Node " << i1p2 << std::endl;
1154             }
1155           #endif
1156             aNode12Indices->Flag |= NMsk_Edge;
1157             aNode12Indices->Flag |= NMsk_Edge;
1158             TIMultiply (XTI2, YTI2, ZTI2);
1159             Interpolation (theList,
1160                            X1  , Y1  , Z1  , X2  , Y2  , Z2  ,
1161                            XTI1, YTI1, ZTI1, XTI2, YTI2, ZTI2,
1162                            theIEdge, U1, U2, rg,
1163                            *aNode11Indices, *aNod11RValues,
1164                            *aNode12Indices, *aNod12RValues,
1165                            i1p1, i1p2, i1, pid1, aTData1, aPISeg1, aPINod1,
1166                            *aNod21Indices, *aNod21RValues,
1167                            *aNod22Indices, *aNod22RValues,
1168                            i2p1, i2p2, i2, pid2, aTData2, aPISeg2, aPINod2);
1169           }
1170         }
1171       }
1172     #ifdef OCCT_DEBUG
1173       else if (DoError)
1174       {
1175         std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
1176         std::cout << theIEdge << " connect 2 without PolygonOnTriangulation" << std::endl;
1177       }
1178     #endif
1179     }
1180   }
1181   else
1182   {  // no connexity
1183     const Handle(Poly_Polygon3D)& aPolyg = BRep_Tool::Polygon3D (theEdge, aLoc);
1184     if (!aPolyg.IsNull())
1185     {
1186       const TColgp_Array1OfPnt& aPol = aPolyg->Nodes();
1187       gp_Trsf aTT = aLoc.Transformation();
1188       const gp_Trsf& aProjTrsf = myProj.Transformation();
1189       aTT.PreMultiply (aProjTrsf);
1190       {
1191         const gp_XYZ& aTTrsfVec = aTT.TranslationPart();
1192         TTLo[0] = aTTrsfVec.X();
1193         TTLo[1] = aTTrsfVec.Y();
1194         TTLo[2] = aTTrsfVec.Z();
1195         const gp_Mat& aTTrsfMat = aTT.VectorialPart();
1196         TTMa[0][0] = aTTrsfMat.Value (1, 1);
1197         TTMa[0][1] = aTTrsfMat.Value (1, 2);
1198         TTMa[0][2] = aTTrsfMat.Value (1, 3);
1199         TTMa[1][0] = aTTrsfMat.Value (2, 1);
1200         TTMa[1][1] = aTTrsfMat.Value (2, 2);
1201         TTMa[1][2] = aTTrsfMat.Value (2, 3);
1202         TTMa[2][0] = aTTrsfMat.Value (3, 1);
1203         TTMa[2][1] = aTTrsfMat.Value (3, 2);
1204         TTMa[2][2] = aTTrsfMat.Value (3, 3);
1205       }
1206       const Standard_Integer aNbPol1 = aPol.Upper();
1207       const gp_XYZ& aP1 = aPol(1).XYZ();
1208       X2 = aP1.X();
1209       Y2 = aP1.Y();
1210       Z2 = aP1.Z();
1211       TTMultiply (X2, Y2, Z2);
1212       XTI2 = X2;
1213       YTI2 = Y2;
1214       ZTI2 = Z2;
1215       TIMultiply (XTI2, YTI2, ZTI2);
1216       
1217       for (Standard_Integer jPol = 2; jPol <= aNbPol1; jPol++)
1218       {
1219         X1   = X2;
1220         Y1   = Y2;
1221         Z1   = Z2;
1222         XTI1 = XTI2;
1223         YTI1 = YTI2;
1224         ZTI1 = ZTI2;
1225         const gp_XYZ& aP2 = aPol(jPol).XYZ();
1226         X2 = aP2.X();
1227         Y2 = aP2.Y();
1228         Z2 = aP2.Z();
1229         TTMultiply (X2, Y2, Z2);
1230         XTI2 = X2;
1231         YTI2 = Y2;
1232         ZTI2 = Z2;
1233         TIMultiply (XTI2, YTI2, ZTI2);
1234         theList.Prepend (HLRAlgo_BiPoint (XTI1, YTI1, ZTI1, XTI2, YTI2, ZTI2,
1235                                           X1  , Y1  , Z1  , X2  , Y2  , Z2,
1236                                           theIEdge, 0));
1237       }
1238     }
1239 #ifdef OCCT_DEBUG
1240     else if (DoError)
1241     {
1242       std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
1243       std::cout << theIEdge << " Isolated, without Polygone 3D" << std::endl;
1244     }
1245 #endif
1246   }
1247 }
1248
1249 //=======================================================================
1250 //function : Interpolation
1251 //purpose  :
1252 //=======================================================================
1253 void HLRBRep_PolyAlgo::Interpolation (HLRAlgo_ListOfBPoint& theList,
1254                                       Standard_Real& theX1,
1255                                       Standard_Real& theY1,
1256                                       Standard_Real& theZ1,
1257                                       Standard_Real& theX2,
1258                                       Standard_Real& theY2,
1259                                       Standard_Real& theZ2,
1260                                       Standard_Real& theXTI1,
1261                                       Standard_Real& theYTI1,
1262                                       Standard_Real& theZTI1,
1263                                       Standard_Real& theXTI2,
1264                                       Standard_Real& theYTI2,
1265                                       Standard_Real& theZTI2,
1266                                       const Standard_Integer theIEdge,
1267                                       Standard_Real& theU1,
1268                                       Standard_Real& theU2,
1269                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod11Indices,
1270                                       HLRAlgo_PolyInternalNode::NodeData& theNod11RValues,
1271                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod12Indices,
1272                                       HLRAlgo_PolyInternalNode::NodeData& theNod12RValues,
1273                                       const Standard_Integer theI1p1,
1274                                       const Standard_Integer theI1p2,
1275                                       const Standard_Integer theI1,
1276                                       const Handle(HLRAlgo_PolyInternalData)& thePid1,
1277                                       HLRAlgo_Array1OfTData*& theTData1,
1278                                       HLRAlgo_Array1OfPISeg*& thePISeg1,
1279                                       HLRAlgo_Array1OfPINod*& thePINod1) const
1280 {
1281   Standard_Boolean mP3P1 = false;
1282   Standard_Real X3 = 0.0, Y3 = 0.0, Z3 = 0.0, XTI3 = 0.0, YTI3 = 0.0, ZTI3 = 0.0, coef3 = 0.0, U3 = 0.0;
1283 //  gp_Pnt P3, PT3;
1284   Standard_Boolean insP3 = Interpolation (theU1, theU2, theNod11RValues, theNod12RValues,
1285                                           X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, mP3P1);
1286   MoveOrInsertPoint (theList,
1287                      theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1288                      theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1289                      theIEdge, theU1, theU2,
1290                      theNod11Indices, theNod11RValues,
1291                      theNod12Indices, theNod12RValues,
1292                      theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1293                      X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, insP3, mP3P1, 0);
1294 }
1295
1296 //=======================================================================
1297 //function : Interpolation
1298 //purpose  :
1299 //=======================================================================
1300 void HLRBRep_PolyAlgo::Interpolation (HLRAlgo_ListOfBPoint& theList,
1301                                       Standard_Real& theX1,
1302                                       Standard_Real& theY1,
1303                                       Standard_Real& theZ1,
1304                                       Standard_Real& theX2,
1305                                       Standard_Real& theY2,
1306                                       Standard_Real& theZ2,
1307                                       Standard_Real& theXTI1,
1308                                       Standard_Real& theYTI1,
1309                                       Standard_Real& theZTI1,
1310                                       Standard_Real& theXTI2,
1311                                       Standard_Real& theYTI2,
1312                                       Standard_Real& theZTI2,
1313                                       const Standard_Integer theIEdge,
1314                                       Standard_Real& theU1,
1315                                       Standard_Real& theU2,
1316                                       const GeomAbs_Shape theRg,
1317                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod11Indices,
1318                                       HLRAlgo_PolyInternalNode::NodeData& theNod11RValues,
1319                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod12Indices,
1320                                       HLRAlgo_PolyInternalNode::NodeData& theNod12RValues,
1321                                       const Standard_Integer theI1p1,
1322                                       const Standard_Integer theI1p2,
1323                                       const Standard_Integer theI1,
1324                                       const Handle(HLRAlgo_PolyInternalData)& thePid1,
1325                                       HLRAlgo_Array1OfTData*& theTData1,
1326                                       HLRAlgo_Array1OfPISeg*& thePISeg1,
1327                                       HLRAlgo_Array1OfPINod*& thePINod1,
1328                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod21Indices,
1329                                       HLRAlgo_PolyInternalNode::NodeData& theNod21RValues,
1330                                       HLRAlgo_PolyInternalNode::NodeIndices& theNod22Indices,
1331                                       HLRAlgo_PolyInternalNode::NodeData& theNod22RValues,
1332                                       const Standard_Integer theI2p1,
1333                                       const Standard_Integer theI2p2,
1334                                       const Standard_Integer theI2,
1335                                       const Handle(HLRAlgo_PolyInternalData)& thePid2,
1336                                       HLRAlgo_Array1OfTData*& theTData2,
1337                                       HLRAlgo_Array1OfPISeg*& thePISeg2,
1338                                       HLRAlgo_Array1OfPINod*& thePINod2) const
1339 {
1340   Standard_Boolean mP3P1 = false, mP4P1 = false;
1341   Standard_Real X3 = 0.0, Y3 = 0.0, Z3 = 0.0, XTI3 = 0.0, YTI3 = 0.0, ZTI3 = 0.0, coef3 = 0.0, U3 = 0.0;
1342   Standard_Real X4 = 0.0, Y4 = 0.0, Z4 = 0.0, XTI4 = 0.0, YTI4 = 0.0, ZTI4 = 0.0, coef4 = 0.0, U4 = 0.0;
1343 //  gp_Pnt P3, PT3, P4, PT4;
1344   Standard_Integer flag = 0;
1345   if (theRg >= GeomAbs_G1) { flag += 1; }
1346   if (theRg >= GeomAbs_G2) { flag += 2; }
1347   const bool insP3 = Interpolation (theU1, theU2, theNod11RValues, theNod12RValues,
1348                                     X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, mP3P1);
1349   const bool insP4 = Interpolation (theU1, theU2, theNod21RValues, theNod22RValues,
1350                                     X4, Y4, Z4, XTI4, YTI4, ZTI4, coef4, U4, mP4P1);
1351   const bool isOK = insP3 || insP4;
1352   if (isOK)
1353   {
1354     if      (!insP4)                               // p1 i1p3 p2
1355     {
1356       MoveOrInsertPoint (theList,
1357                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1358                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1359                          theIEdge, theU1, theU2,
1360                          theNod11Indices, theNod11RValues,
1361                          theNod12Indices, theNod12RValues,
1362                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1363                          theNod21Indices, theNod21RValues,
1364                          theNod22Indices, theNod22RValues,
1365                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1366                          X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, insP3, mP3P1, flag);
1367     }
1368     else if (!insP3)                               // p1 i2p4 p2
1369     {
1370       MoveOrInsertPoint (theList,
1371                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1372                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1373                          theIEdge, theU1, theU2,
1374                          theNod21Indices, theNod21RValues,
1375                          theNod22Indices, theNod22RValues,
1376                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1377                          theNod11Indices, theNod11RValues,
1378                          theNod12Indices, theNod12RValues,
1379                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1380                          X4, Y4, Z4, XTI4, YTI4, ZTI4, coef4, U4, insP4, mP4P1, flag);
1381     }
1382     else if (Abs(coef4 - coef3) < myTolSta)       // p1 i1p3-i2p4 p2
1383     {
1384       MoveOrInsertPoint (theList,
1385                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1386                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1387                          theIEdge, theU1, theU2,
1388                          theNod21Indices, theNod21RValues,
1389                          theNod22Indices, theNod22RValues,
1390                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1391                          theNod11Indices, theNod11RValues,
1392                          theNod12Indices, theNod12RValues,
1393                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1394                          X4, Y4, Z4, XTI4, YTI4, ZTI4, coef4, U4, insP4, mP4P1, flag);
1395     }
1396     else if (coef4 < coef3)                        // p1 i2p4 i1p3 p2
1397     {
1398       MoveOrInsertPoint (theList,
1399                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1400                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1401                          theIEdge, theU1, theU2,
1402                          theNod21Indices, theNod21RValues,
1403                          theNod22Indices, theNod22RValues,
1404                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1405                          theNod11Indices, theNod11RValues,
1406                          theNod12Indices, theNod12RValues,
1407                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1408                          X4, Y4, Z4, XTI4, YTI4, ZTI4, coef4, U4, insP4, mP4P1,
1409                          X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, insP3, mP3P1, flag);
1410     }
1411     else                                           // p1 i1p3 i2p4 p2
1412     {
1413       MoveOrInsertPoint (theList,
1414                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1415                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1416                          theIEdge, theU1, theU2,
1417                          theNod11Indices, theNod11RValues,
1418                          theNod12Indices, theNod12RValues,
1419                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1420                          theNod21Indices, theNod21RValues,
1421                          theNod22Indices, theNod22RValues,
1422                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1423                          X3, Y3, Z3, XTI3, YTI3, ZTI3, coef3, U3, insP3, mP3P1,
1424                          X4, Y4, Z4, XTI4, YTI4, ZTI4, coef4, U4, insP4, mP4P1, flag);
1425     }
1426   }
1427   else                                             // p1 p2
1428   {
1429     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1430                                       theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  , theIEdge,
1431                                       theI1  , theI1p1, theI1p2, theI2  , theI2p1, theI2p2, flag));
1432   }
1433 }
1434
1435 //=======================================================================
1436 //function : Interpolation
1437 //purpose  :
1438 //=======================================================================
1439 Standard_Boolean HLRBRep_PolyAlgo::Interpolation (const Standard_Real theU1,
1440                                                   const Standard_Real theU2,
1441                                                   HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
1442                                                   HLRAlgo_PolyInternalNode::NodeData& theNod2RValues,
1443                                                   Standard_Real& theX3,
1444                                                   Standard_Real& theY3,
1445                                                   Standard_Real& theZ3,
1446                                                   Standard_Real& theXTI3,
1447                                                   Standard_Real& theYTI3,
1448                                                   Standard_Real& theZTI3,
1449                                                   Standard_Real& theCoef3,
1450                                                   Standard_Real& theU3,
1451                                                   Standard_Boolean& themP3P1) const
1452 {
1453   if (NewNode (theNod1RValues, theNod2RValues, theCoef3, themP3P1))
1454   {
1455     theU3 = theU1 + (theU2 - theU1) * theCoef3;
1456     const gp_Pnt& aP3 = myBCurv.Value (theU3);
1457     theXTI3 = theX3 = aP3.X();
1458     theYTI3 = theY3 = aP3.Y();
1459     theZTI3 = theZ3 = aP3.Z();
1460     TMultiply (theX3, theY3, theZ3);
1461     return Standard_True;
1462   }
1463
1464   theX3 = theY3 = theZ3 = theXTI3 = theYTI3 = theZTI3 = theCoef3 = theU3 = 0.0;
1465   return Standard_False;
1466 }
1467
1468 //=======================================================================
1469 //function : MoveOrInsertPoint
1470 //purpose  :
1471 //=======================================================================
1472 void HLRBRep_PolyAlgo::MoveOrInsertPoint (HLRAlgo_ListOfBPoint& theList,
1473                                           Standard_Real& theX1,
1474                                           Standard_Real& theY1,
1475                                           Standard_Real& theZ1,
1476                                           Standard_Real& theX2,
1477                                           Standard_Real& theY2,
1478                                           Standard_Real& theZ2,
1479                                           Standard_Real& theXTI1,
1480                                           Standard_Real& theYTI1,
1481                                           Standard_Real& theZTI1,
1482                                           Standard_Real& theXTI2,
1483                                           Standard_Real& theYTI2,
1484                                           Standard_Real& theZTI2,
1485                                           const Standard_Integer theIEdge,
1486                                           Standard_Real& theU1,
1487                                           Standard_Real& theU2,
1488                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod11Indices,
1489                                           HLRAlgo_PolyInternalNode::NodeData& theNod11RValues,
1490                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod12Indices,
1491                                           HLRAlgo_PolyInternalNode::NodeData& theNod12RValues,
1492                                           const Standard_Integer theI1p1,
1493                                           const Standard_Integer theI1p2,
1494                                           const Standard_Integer theI1,
1495                                           const Handle(HLRAlgo_PolyInternalData)& thePid1,
1496                                           HLRAlgo_Array1OfTData*& theTData1,
1497                                           HLRAlgo_Array1OfPISeg*& thePISeg1,
1498                                           HLRAlgo_Array1OfPINod*& thePINod1,
1499                                           const Standard_Real theX3,
1500                                           const Standard_Real theY3,
1501                                           const Standard_Real theZ3,
1502                                           const Standard_Real theXTI3,
1503                                           const Standard_Real theYTI3,
1504                                           const Standard_Real theZTI3,
1505                                           const Standard_Real theCoef3,
1506                                           const Standard_Real theU3,
1507                                           const Standard_Boolean theInsP3,
1508                                           const Standard_Boolean themP3P1,
1509                                           const Standard_Integer theFlag) const
1510 {
1511   HLRAlgo_Array1OfTData* aTData2 = NULL;
1512   HLRAlgo_Array1OfPISeg* aPISeg2 = NULL;
1513   HLRAlgo_Array1OfPINod* aPINod2 = NULL;
1514   Standard_Boolean anIns3 = theInsP3;
1515   if (anIns3 && themP3P1)                               // P1 ---> P3
1516   {
1517     if (!(theNod11Indices.Flag & NMsk_Vert) && theCoef3 < myTolSta)
1518     {
1519       anIns3 = Standard_False;
1520       ChangeNode (theI1p1, theI1p2,
1521                   theNod11Indices, theNod11RValues,
1522                   theNod12Indices, theNod12RValues,
1523                   theCoef3, theX3, theY3, theZ3, Standard_True,
1524                   *theTData1, *thePISeg1, *thePINod1);
1525       theX1   = theX3;
1526       theY1   = theY3;
1527       theZ1   = theZ3;
1528       theXTI1 = theXTI3;
1529       theYTI1 = theYTI3;
1530       theZTI1 = theZTI3;
1531       theU1   = theU3;
1532       theNod11RValues.Point = gp_XYZ(theX3, theY3, theZ3);
1533       if      (theNod11Indices.Edg1 == theIEdge) { theNod11RValues.PCu1 = theU3; }
1534       else if (theNod11Indices.Edg2 == theIEdge) { theNod11RValues.PCu2 = theU3; }
1535 #ifdef OCCT_DEBUG
1536       else
1537       {
1538         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1539         std::cout << "Parameter error on Node " << theI1p1 << std::endl;
1540       }
1541 #endif
1542       theNod11RValues.Scal  = 0;
1543       theNod11Indices.Flag |= NMsk_OutL;
1544       UpdateAroundNode (theI1p1, theNod11Indices, *theTData1, *thePISeg1, *thePINod1);
1545       HLRAlgo_BiPoint::PointsT& aPoints = theList.First().Points();
1546       aPoints.PntP2 = gp_XYZ(theX3, theY3, theZ3);
1547       aPoints.Pnt2 = gp_XYZ(theXTI3, theYTI3, theZTI3);
1548     }
1549   }
1550   if (anIns3 && !themP3P1)                              // P2 ---> P3
1551   {
1552     if (!(theNod12Indices.Flag & NMsk_Vert) && theCoef3 > myTolEnd)
1553     {
1554       anIns3 = Standard_False;
1555       ChangeNode (theI1p1, theI1p2,
1556                   theNod11Indices, theNod11RValues,
1557                   theNod12Indices, theNod12RValues,
1558                   theCoef3, theX3, theY3, theZ3, Standard_False,
1559                   *theTData1, *thePISeg1, *thePINod1);
1560       theX2   = theX3;
1561       theY2   = theY3;
1562       theZ2   = theZ3;
1563       theXTI2 = theXTI3;
1564       theYTI2 = theYTI3;
1565       theZTI2 = theZTI3;
1566       theU2   = theU3;
1567       theNod12RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1568       if      (theNod12Indices.Edg1 == theIEdge) { theNod12RValues.PCu1 = theU3; }
1569       else if (theNod12Indices.Edg2 == theIEdge) { theNod12RValues.PCu2 = theU3; }
1570 #ifdef OCCT_DEBUG
1571       else
1572       {
1573         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1574         std::cout << "Parameter error on Node " << theI1p2 << std::endl;
1575       }
1576 #endif
1577       theNod12RValues.Scal  = 0;
1578       theNod12Indices.Flag |= NMsk_OutL;
1579       UpdateAroundNode (theI1p2, theNod12Indices, *theTData1, *thePISeg1, *thePINod1);
1580     }
1581   }
1582   if (anIns3)                                        // p1 i1p3 p2
1583   {
1584     Standard_Integer anI1p3 = thePid1->AddNode (theNod11RValues, theNod12RValues, thePINod1, aPINod2, theCoef3, theX3, theY3, theZ3);
1585     const Handle(HLRAlgo_PolyInternalNode)& aPi1p3 = thePINod1->ChangeValue  (anI1p3);
1586     HLRAlgo_PolyInternalNode::NodeIndices& aNod13Indices = aPi1p3->Indices();
1587     HLRAlgo_PolyInternalNode::NodeData& aNod13RValues = aPi1p3->Data();
1588     aNod13Indices.Edg1  = theIEdge;
1589     aNod13RValues.PCu1  = theU3;
1590     aNod13RValues.Scal  = 0;
1591     aNod13Indices.Flag |= NMsk_OutL;
1592     aNod13Indices.Flag |= NMsk_Edge;
1593     thePid1->UpdateLinks (theI1p1, theI1p2, anI1p3,
1594                           theTData1, aTData2, thePISeg1, aPISeg2, thePINod1, aPINod2);
1595     UpdateAroundNode (anI1p3, aNod13Indices, *theTData1, *thePISeg1, *thePINod1);
1596     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI3, theYTI3, theZTI3,
1597                                       theX1  , theY1  , theZ1  , theX3  , theY3  , theZ3  ,   theIEdge,
1598                                       theI1  , theI1p1, anI1p3, theFlag));
1599     theList.Prepend (HLRAlgo_BiPoint (theXTI3, theYTI3, theZTI3, theXTI2, theYTI2, theZTI2,
1600                                       theX3  , theY3  , theZ3  , theX2  , theY2  , theZ2  ,   theIEdge,
1601                                       theI1  , anI1p3, theI1p2, theFlag));
1602   }
1603   else                                             // p1 p2
1604   {
1605     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1606                                       theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,   theIEdge,
1607                                       theI1  , theI1p1, theI1p2, theFlag));
1608   }
1609 }
1610
1611 //=======================================================================
1612 //function : MoveOrInsertPoint
1613 //purpose  :
1614 //=======================================================================
1615 void HLRBRep_PolyAlgo::MoveOrInsertPoint (HLRAlgo_ListOfBPoint& theList,
1616                                           Standard_Real& theX1,
1617                                           Standard_Real& theY1,
1618                                           Standard_Real& theZ1,
1619                                           Standard_Real& theX2,
1620                                           Standard_Real& theY2,
1621                                           Standard_Real& theZ2,
1622                                           Standard_Real& theXTI1,
1623                                           Standard_Real& theYTI1,
1624                                           Standard_Real& theZTI1,
1625                                           Standard_Real& theXTI2,
1626                                           Standard_Real& theYTI2,
1627                                           Standard_Real& theZTI2,
1628                                           const Standard_Integer theIEdge,
1629                                           Standard_Real& theU1,
1630                                           Standard_Real& theU2,
1631                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod11Indices,
1632                                           HLRAlgo_PolyInternalNode::NodeData& theNod11RValues,
1633                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod12Indices,
1634                                           HLRAlgo_PolyInternalNode::NodeData& theNod12RValues,
1635                                           const Standard_Integer theI1p1,
1636                                           const Standard_Integer theI1p2,
1637                                           const Standard_Integer theI1,
1638                                           const Handle(HLRAlgo_PolyInternalData)& thePid1,
1639                                           HLRAlgo_Array1OfTData*& theTData1,
1640                                           HLRAlgo_Array1OfPISeg*& thePISeg1,
1641                                           HLRAlgo_Array1OfPINod*& thePINod1,
1642                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod21Indices,
1643                                           HLRAlgo_PolyInternalNode::NodeData& theNod21RValues,
1644                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod22Indices,
1645                                           HLRAlgo_PolyInternalNode::NodeData& theNod22RValues,
1646                                           const Standard_Integer theI2p1,
1647                                           const Standard_Integer theI2p2,
1648                                           const Standard_Integer theI2,
1649                                           const Handle(HLRAlgo_PolyInternalData)& thePid2,
1650                                           HLRAlgo_Array1OfTData*& theTData2,
1651                                           HLRAlgo_Array1OfPISeg*& thePISeg2,
1652                                           HLRAlgo_Array1OfPINod*& thePINod2,
1653                                           const Standard_Real theX3,
1654                                           const Standard_Real theY3,
1655                                           const Standard_Real theZ3,
1656                                           const Standard_Real theXTI3,
1657                                           const Standard_Real theYTI3,
1658                                           const Standard_Real theZTI3,
1659                                           const Standard_Real theCoef3,
1660                                           const Standard_Real theU3,
1661                                           const Standard_Boolean theInsP3,
1662                                           const Standard_Boolean themP3P1,
1663                                           const Standard_Integer theFlag) const
1664 {
1665   Standard_Boolean anIns3 = theInsP3;
1666   if (anIns3 && themP3P1)                              // P1 ---> P3
1667   {
1668     if (!(theNod11Indices.Flag & NMsk_Vert) && theCoef3 < myTolSta)
1669     {
1670       anIns3 = Standard_False;
1671       ChangeNode (theI1p1, theI1p2,
1672                   theNod11Indices, theNod11RValues,
1673                   theNod12Indices, theNod12RValues,
1674                   theCoef3, theX3, theY3, theZ3, Standard_True,
1675                   *theTData1, *thePISeg1, *thePINod1);
1676       ChangeNode (theI2p1, theI2p2,
1677                   theNod21Indices, theNod21RValues,
1678                   theNod22Indices, theNod22RValues,
1679                   theCoef3, theX3, theY3, theZ3, Standard_True,
1680                   *theTData2, *thePISeg2, *thePINod2);
1681       theX1   = theX3;
1682       theY1   = theY3;
1683       theZ1   = theZ3;
1684       theXTI1 = theXTI3;
1685       theYTI1 = theYTI3;
1686       theZTI1 = theZTI3;
1687       theU1   = theU3;
1688       theNod11RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1689       if      (theNod11Indices.Edg1 == theIEdge) { theNod11RValues.PCu1 = theU3; }
1690       else if (theNod11Indices.Edg2 == theIEdge) { theNod11RValues.PCu2 = theU3; }
1691 #ifdef OCCT_DEBUG
1692       else
1693       {
1694         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1695         std::cout << "Parameter error on Node " << theI1p1 << std::endl;
1696       }
1697 #endif
1698       theNod11RValues.Scal  = 0;
1699       theNod11Indices.Flag |= NMsk_OutL;
1700       UpdateAroundNode (theI1p1, theNod11Indices, *theTData1, *thePISeg1, *thePINod1);
1701       theNod21RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1702       if      (theNod21Indices.Edg1 == theIEdge) { theNod21RValues.PCu1 = theU3; }
1703       else if (theNod21Indices.Edg2 == theIEdge) { theNod21RValues.PCu2 = theU3; }
1704 #ifdef OCCT_DEBUG
1705       else
1706       {
1707         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1708         std::cout << "Parameter error on Node " << theI2p1 << std::endl;
1709       }
1710 #endif
1711       theNod21RValues.Scal  = 0;
1712       theNod21Indices.Flag |= NMsk_OutL;
1713       UpdateAroundNode (theI2p1, theNod21Indices, *theTData2, *thePISeg2, *thePINod2);
1714       HLRAlgo_BiPoint::PointsT& aPoints = theList.First().Points();
1715       aPoints.PntP2 = gp_XYZ(theX3, theY3, theZ3);
1716       aPoints.Pnt2 = gp_XYZ(theXTI3, theYTI3, theZTI3);
1717     }
1718   }
1719   if (anIns3 && !themP3P1)                             // P2 ---> P3
1720   {
1721     if (!(theNod12Indices.Flag & NMsk_Vert) && theCoef3 > myTolEnd)
1722     {
1723       anIns3 = Standard_False;
1724       ChangeNode (theI1p1, theI1p2,
1725                   theNod11Indices, theNod11RValues,
1726                   theNod12Indices, theNod12RValues,
1727                   theCoef3, theX3, theY3, theZ3, Standard_False,
1728                   *theTData1, *thePISeg1, *thePINod1);
1729       ChangeNode (theI2p1, theI2p2,
1730                   theNod21Indices, theNod21RValues,
1731                   theNod22Indices, theNod22RValues,
1732                   theCoef3, theX3, theY3, theZ3, Standard_False,
1733                   *theTData2, *thePISeg2, *thePINod2);
1734       theX2   = theX3;
1735       theY2   = theY3;
1736       theZ2   = theZ3;
1737       theXTI2 = theXTI3;
1738       theYTI2 = theYTI3;
1739       theZTI2 = theZTI3;
1740       theU2   = theU3;
1741       theNod12RValues.Point = gp_XYZ(theX3, theY3, theZ3);
1742       if      (theNod12Indices.Edg1 == theIEdge) { theNod12RValues.PCu1 = theU3; }
1743       else if (theNod12Indices.Edg2 == theIEdge) { theNod12RValues.PCu2 = theU3; }
1744 #ifdef OCCT_DEBUG
1745       else
1746       {
1747         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1748         std::cout << "Parameter error on Node " << theI1p2 << std::endl;
1749       }
1750 #endif
1751       theNod12RValues.Scal  = 0;
1752       theNod12Indices.Flag |= NMsk_OutL;
1753       UpdateAroundNode (theI1p2, theNod12Indices, *theTData1, *thePISeg1, *thePINod1);
1754       theNod22RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1755       if      (theNod22Indices.Edg1 == theIEdge) { theNod22RValues.PCu1 = theU3; }
1756       else if (theNod22Indices.Edg2 == theIEdge) { theNod22RValues.PCu2 = theU3; }
1757 #ifdef OCCT_DEBUG
1758       else
1759       {
1760         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1761         std::cout << "Parameter error on Node " << theI2p2 << std::endl;
1762       }
1763 #endif
1764       theNod22RValues.Scal = 0;
1765       theNod22Indices.Flag |=  NMsk_OutL;
1766       UpdateAroundNode (theI2p2, theNod22Indices, *theTData2, *thePISeg2, *thePINod2);
1767     }
1768   }
1769   if (anIns3)                                       // p1 i1p3 p2
1770   {
1771     Standard_Integer anI1p3 = thePid1->AddNode (theNod11RValues, theNod12RValues, thePINod1, thePINod2, theCoef3, theX3, theY3, theZ3);
1772     Standard_Integer anI2p3 = thePid2->AddNode (theNod21RValues, theNod22RValues, thePINod2, thePINod1, theCoef3, theX3, theY3, theZ3);
1773     const Handle(HLRAlgo_PolyInternalNode)& aPi1p3 = thePINod1->ChangeValue (anI1p3);
1774     HLRAlgo_PolyInternalNode::NodeIndices& aNod13Indices = aPi1p3->Indices();
1775     HLRAlgo_PolyInternalNode::NodeData& aNod13RValues = aPi1p3->Data();
1776     const Handle(HLRAlgo_PolyInternalNode)& aPi2p3 = thePINod2->ChangeValue (anI2p3);
1777     HLRAlgo_PolyInternalNode::NodeIndices& aNod23Indices = aPi2p3->Indices();
1778     HLRAlgo_PolyInternalNode::NodeData& aNod23RValues = aPi2p3->Data();
1779     aNod13Indices.Edg1  = theIEdge;
1780     aNod13RValues.PCu1  = theU3;
1781     aNod13RValues.Scal  = 0;
1782     aNod13Indices.Flag |= NMsk_OutL;
1783     aNod13Indices.Flag |= NMsk_Edge;
1784     aNod23Indices.Edg1  = theIEdge;
1785     aNod23RValues.PCu1  = theU3;
1786     aNod23RValues.Scal  = 0;
1787     aNod23Indices.Flag |= NMsk_OutL;
1788     aNod23Indices.Flag |= NMsk_Edge;
1789     thePid1->UpdateLinks (theI1p1, theI1p2, anI1p3,
1790                           theTData1, theTData2, thePISeg1, thePISeg2, thePINod1, thePINod2);
1791     thePid2->UpdateLinks (theI2p1, theI2p2, anI2p3,
1792                           theTData2, theTData1, thePISeg2, thePISeg1, thePINod2, thePINod1);
1793     UpdateAroundNode (anI1p3, aNod13Indices, *theTData1, *thePISeg1, *thePINod1);
1794     UpdateAroundNode (anI2p3, aNod23Indices, *theTData2, *thePISeg2, *thePINod2);
1795     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI3, theYTI3, theZTI3,
1796                                       theX1  , theY1  , theZ1  , theX3  , theY3  , theZ3  ,   theIEdge,
1797                                       theI1  , theI1p1, anI1p3,  theI2  , theI2p1, anI2p3, theFlag));
1798     theList.Prepend (HLRAlgo_BiPoint (theXTI3, theYTI3, theZTI3, theXTI2, theYTI2, theZTI2,
1799                                       theX3  , theY3  , theZ3  , theX2  , theY2  , theZ2  ,   theIEdge,
1800                                       theI1  , anI1p3,  theI1p2, theI2  , anI2p3, theI2p2, theFlag));
1801   }
1802   else                                             // p1 p2
1803   {
1804     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1805                                       theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,   theIEdge,
1806                                       theI1  , theI1p1, theI1p2, theI2  , theI2p1, theI2p2, theFlag));
1807   }
1808 }
1809
1810 //=======================================================================
1811 //function : MoveOrInsertPoint
1812 //purpose  :
1813 //=======================================================================
1814 void HLRBRep_PolyAlgo::MoveOrInsertPoint (HLRAlgo_ListOfBPoint& theList,
1815                                           Standard_Real& theX1,
1816                                           Standard_Real& theY1,
1817                                           Standard_Real& theZ1,
1818                                           Standard_Real& theX2,
1819                                           Standard_Real& theY2,
1820                                           Standard_Real& theZ2,
1821                                           Standard_Real& theXTI1,
1822                                           Standard_Real& theYTI1,
1823                                           Standard_Real& theZTI1,
1824                                           Standard_Real& theXTI2,
1825                                           Standard_Real& theYTI2,
1826                                           Standard_Real& theZTI2,
1827                                           const Standard_Integer theIEdge,
1828                                           Standard_Real& theU1,
1829                                           Standard_Real& theU2,
1830                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod11Indices,
1831                                           HLRAlgo_PolyInternalNode::NodeData& theNod11RValues,
1832                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod12Indices,
1833                                           HLRAlgo_PolyInternalNode::NodeData& theNod12RValues,
1834                                           const Standard_Integer theI1p1,
1835                                           const Standard_Integer theI1p2,
1836                                           const Standard_Integer theI1,
1837                                           const Handle(HLRAlgo_PolyInternalData)& thePid1,
1838                                           HLRAlgo_Array1OfTData*& theTData1,
1839                                           HLRAlgo_Array1OfPISeg*& thePISeg1,
1840                                           HLRAlgo_Array1OfPINod*& thePINod1,
1841                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod21Indices,
1842                                           HLRAlgo_PolyInternalNode::NodeData& theNod21RValues,
1843                                           HLRAlgo_PolyInternalNode::NodeIndices& theNod22Indices,
1844                                           HLRAlgo_PolyInternalNode::NodeData& theNod22RValues,
1845                                           const Standard_Integer theI2p1,
1846                                           const Standard_Integer theI2p2,
1847                                           const Standard_Integer theI2,
1848                                           const Handle(HLRAlgo_PolyInternalData)& thePid2,
1849                                           HLRAlgo_Array1OfTData*& theTData2,
1850                                           HLRAlgo_Array1OfPISeg*& thePISeg2,
1851                                           HLRAlgo_Array1OfPINod*& thePINod2,
1852                                           const Standard_Real theX3,
1853                                           const Standard_Real theY3,
1854                                           const Standard_Real theZ3,
1855                                           const Standard_Real theXTI3,
1856                                           const Standard_Real theYTI3,
1857                                           const Standard_Real theZTI3,
1858                                           const Standard_Real theCoef3,
1859                                           const Standard_Real theU3,
1860                                           const Standard_Boolean theInsP3,
1861                                           const Standard_Boolean themP3P1,
1862                                           const Standard_Real theX4,
1863                                           const Standard_Real theY4,
1864                                           const Standard_Real theZ4,
1865                                           const Standard_Real theXTI4,
1866                                           const Standard_Real theYTI4,
1867                                           const Standard_Real theZTI4,
1868                                           const Standard_Real theCoef4,
1869                                           const Standard_Real theU4,
1870                                           const Standard_Boolean theInsP4,
1871                                           const Standard_Boolean themP4P1,
1872                                           const Standard_Integer theFlag) const
1873 {
1874   Standard_Boolean anIns3 = theInsP3;
1875   Standard_Boolean anIns4 = theInsP4;
1876   if (anIns3 && themP3P1)                              // P1 ---> P3
1877   {
1878     if (!(theNod11Indices.Flag & NMsk_Vert) && theCoef3 < myTolSta)
1879     {
1880       anIns3 = Standard_False;
1881       ChangeNode (theI1p1, theI1p2,
1882                   theNod11Indices, theNod11RValues,
1883                   theNod12Indices, theNod12RValues,
1884                   theCoef3, theX3, theY3, theZ3, Standard_True,
1885                   *theTData1, *thePISeg1, *thePINod1);
1886       ChangeNode (theI2p1, theI2p2,
1887                   theNod21Indices, theNod21RValues,
1888                   theNod22Indices, theNod22RValues,
1889                   theCoef3, theX3, theY3, theZ3, Standard_True,
1890                   *theTData2, *thePISeg2, *thePINod2);
1891       theX1   = theX3;
1892       theY1   = theY3;
1893       theZ1   = theZ3;
1894       theXTI1 = theXTI3;
1895       theYTI1 = theYTI3;
1896       theZTI1 = theZTI3;
1897       theU1   = theU3;
1898       theNod11RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1899       if      (theNod11Indices.Edg1 == theIEdge) { theNod11RValues.PCu1 = theU3; }
1900       else if (theNod11Indices.Edg2 == theIEdge) { theNod11RValues.PCu2 = theU3; }
1901 #ifdef OCCT_DEBUG
1902       else
1903       {
1904         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1905         std::cout << "Parameter error on Node " << theI1p1 << std::endl;
1906       }
1907 #endif
1908       theNod11RValues.Scal  = 0;
1909       theNod11Indices.Flag |= NMsk_OutL;
1910       UpdateAroundNode (theI1p1, theNod11Indices, *theTData1, *thePISeg1, *thePINod1);
1911       theNod21RValues.Point = gp_XYZ (theX3, theY3, theZ3);
1912       if      (theNod21Indices.Edg1 == theIEdge) { theNod21RValues.PCu1 = theU3; }
1913       else if (theNod21Indices.Edg2 == theIEdge) { theNod21RValues.PCu2 = theU3; }
1914 #ifdef OCCT_DEBUG
1915       else
1916       {
1917         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1918         std::cout << "Parameter error on Node " << theI2p1 << std::endl;
1919       }
1920 #endif
1921       theNod21RValues.Scal  = 0;
1922       theNod21Indices.Flag |= NMsk_OutL;
1923       UpdateAroundNode (theI2p1, theNod21Indices, *theTData2, *thePISeg2, *thePINod2);
1924       HLRAlgo_BiPoint::PointsT& aPoints = theList.First().Points();
1925       aPoints.PntP2 = gp_XYZ (theX3, theY3, theZ3);
1926       aPoints.Pnt2 = gp_XYZ (theXTI3, theYTI3, theZTI3);
1927     }
1928   }
1929   if (anIns4 && !themP4P1)                             // P2 ---> P4
1930   {
1931     if (!(theNod12Indices.Flag & NMsk_Vert) && theCoef4 > myTolEnd)
1932     {
1933       anIns4 = Standard_False;
1934       ChangeNode (theI2p1, theI2p2,
1935                   theNod21Indices, theNod21RValues,
1936                   theNod22Indices, theNod22RValues,
1937                   theCoef4, theX4, theY4, theZ4, Standard_False,
1938                   *theTData2, *thePISeg2, *thePINod2);
1939       ChangeNode (theI1p1, theI1p2,
1940                   theNod11Indices, theNod11RValues,
1941                   theNod12Indices, theNod12RValues,
1942                   theCoef4, theX4, theY4, theZ4, Standard_False,
1943                   *theTData1, *thePISeg1, *thePINod1);
1944       theX2   = theX4;
1945       theY2   = theY4;
1946       theZ2   = theZ4;
1947       theXTI2 = theXTI4;
1948       theYTI2 = theYTI4;
1949       theZTI2 = theZTI4;
1950       theU2   = theU4;
1951       theNod12RValues.Point = gp_XYZ (theX4, theY4, theZ4);
1952       if      (theNod12Indices.Edg1 == theIEdge) { theNod12RValues.PCu1 = theU4; }
1953       else if (theNod12Indices.Edg2 == theIEdge) { theNod12RValues.PCu2 = theU4; }
1954 #ifdef OCCT_DEBUG
1955       else
1956       {
1957         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1958         std::cout << "Parameter error on Node " << theI1p2 << std::endl;
1959       }
1960 #endif
1961       theNod12RValues.Scal  = 0;
1962       theNod12Indices.Flag |= NMsk_OutL;
1963       UpdateAroundNode (theI1p2, theNod12Indices, *theTData1, *thePISeg1, *thePINod1);
1964       theNod22RValues.Point = gp_XYZ (theX4, theY4, theZ4);
1965       if      (theNod22Indices.Edg1 == theIEdge) { theNod22RValues.PCu1 = theU4; }
1966       else if (theNod22Indices.Edg2 == theIEdge) { theNod22RValues.PCu2 = theU4; }
1967 #ifdef OCCT_DEBUG
1968       else
1969       {
1970         std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
1971         std::cout << "Parameter error on Node " << theI2p2 << std::endl;
1972       }
1973 #endif
1974       theNod22RValues.Scal  = 0;
1975       theNod22Indices.Flag |= NMsk_OutL;
1976       UpdateAroundNode (theI2p2, theNod22Indices, *theTData2, *thePISeg2, *thePINod2);
1977     }
1978   }
1979   if (anIns3 || anIns4)
1980   {
1981     if      (!anIns4)                                // p1 i1p3 p2
1982     {
1983       MoveOrInsertPoint (theList,
1984                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1985                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
1986                          theIEdge, theU1, theU2,
1987                          theNod11Indices, theNod11RValues,
1988                          theNod12Indices, theNod12RValues,
1989                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
1990                          theNod21Indices, theNod21RValues,
1991                          theNod22Indices, theNod22RValues,
1992                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
1993                          theX3, theY3, theZ3, theXTI3, theYTI3, theZTI3, theCoef3, theU3, theInsP3, themP3P1, theFlag);
1994     }
1995     else if (!anIns3)                                // p1 i2p4 p2
1996     {
1997       MoveOrInsertPoint (theList,
1998                          theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  ,
1999                          theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
2000                          theIEdge, theU1, theU2,
2001                          theNod21Indices, theNod21RValues,
2002                          theNod22Indices, theNod22RValues,
2003                          theI2p1, theI2p2, theI2, thePid2, theTData2, thePISeg2, thePINod2,
2004                          theNod11Indices, theNod11RValues,
2005                          theNod12Indices, theNod12RValues,
2006                          theI1p1, theI1p2, theI1, thePid1, theTData1, thePISeg1, thePINod1,
2007                          theX4, theY4, theZ4, theXTI4, theYTI4, theZTI4, theCoef4, theU4, theInsP4, themP4P1, theFlag);
2008     }
2009     else                                          // p1 i1p3 i2p4 p2
2010     {
2011       Standard_Integer anI1p3 = thePid1->AddNode (theNod11RValues, theNod12RValues, thePINod1, thePINod2, theCoef3, theX3, theY3, theZ3);
2012       Standard_Integer anI2p3 = thePid2->AddNode (theNod21RValues, theNod22RValues, thePINod2, thePINod1, theCoef3, theX3, theY3, theZ3);
2013       Standard_Integer anI1p4 = thePid1->AddNode (theNod11RValues, theNod12RValues, thePINod1, thePINod2, theCoef4, theX4, theY4, theZ4);
2014       Standard_Integer anI2p4 = thePid2->AddNode (theNod21RValues, theNod22RValues, thePINod2, thePINod1, theCoef4, theX4, theY4, theZ4);
2015       const Handle(HLRAlgo_PolyInternalNode)& aPi1p3 = thePINod1->ChangeValue (anI1p3);
2016       HLRAlgo_PolyInternalNode::NodeIndices& aNod13Indices = aPi1p3->Indices();
2017       HLRAlgo_PolyInternalNode::NodeData& aNod13RValues = aPi1p3->Data();
2018       const Handle(HLRAlgo_PolyInternalNode)& aPi1p4 = thePINod1->ChangeValue (anI1p4);
2019       HLRAlgo_PolyInternalNode::NodeIndices& aNod14Indices = aPi1p4->Indices();
2020       HLRAlgo_PolyInternalNode::NodeData& aNod14RValues = aPi1p4->Data();
2021       const Handle(HLRAlgo_PolyInternalNode)& aPi2p3 = thePINod2->ChangeValue (anI2p3);
2022       HLRAlgo_PolyInternalNode::NodeIndices& aNod23Indices = aPi2p3->Indices();
2023       HLRAlgo_PolyInternalNode::NodeData& aNod23RValues = aPi2p3->Data();
2024       const Handle(HLRAlgo_PolyInternalNode)& aPi2p4 =  thePINod2->ChangeValue (anI2p4);
2025       HLRAlgo_PolyInternalNode::NodeIndices& aNod24Indices = aPi2p4->Indices();
2026       HLRAlgo_PolyInternalNode::NodeData& aNod24RValues = aPi2p4->Data();
2027       aNod13Indices.Edg1  = theIEdge;
2028       aNod13RValues.PCu1  = theU3;
2029       aNod13RValues.Scal  = 0;
2030       aNod13Indices.Flag |= NMsk_OutL;
2031       aNod13Indices.Flag |= NMsk_Edge;
2032       aNod23Indices.Edg1  = theIEdge;
2033       aNod23RValues.PCu1  = theU3;
2034       aNod23RValues.Scal  = 0;
2035       aNod23Indices.Flag |= NMsk_OutL;
2036       aNod23Indices.Flag |= NMsk_Edge;
2037       aNod14Indices.Edg1  = theIEdge;
2038       aNod14RValues.PCu1  = theU4;
2039       aNod14RValues.Scal  = 0;
2040       aNod14Indices.Flag |= NMsk_OutL;
2041       aNod14Indices.Flag |= NMsk_Edge;
2042       aNod24Indices.Edg1  = theIEdge;
2043       aNod24RValues.PCu1  = theU4;
2044       aNod24RValues.Scal  = 0;
2045       aNod24Indices.Flag |= NMsk_OutL;
2046       aNod24Indices.Flag |= NMsk_Edge;
2047       thePid1->UpdateLinks (theI1p1, theI1p2, anI1p3,
2048                             theTData1, theTData2, thePISeg1, thePISeg2, thePINod1, thePINod2);
2049       thePid2->UpdateLinks (theI2p1, theI2p2, anI2p3,
2050                             theTData2, theTData1, thePISeg2, thePISeg1, thePINod2, thePINod1);
2051       thePid2->UpdateLinks (anI2p3, theI2p2, anI2p4,
2052                             theTData2, theTData1, thePISeg2, thePISeg1, thePINod2, thePINod1);
2053       thePid1->UpdateLinks (anI1p3, theI1p2, anI1p4,
2054                             theTData1, theTData2, thePISeg1, thePISeg2, thePINod1, thePINod2);
2055       UpdateAroundNode (anI1p3, aNod13Indices, *theTData1, *thePISeg1, *thePINod1);
2056       UpdateAroundNode (anI2p3, aNod23Indices, *theTData2, *thePISeg2, *thePINod2);
2057       UpdateAroundNode (anI1p4, aNod14Indices, *theTData1, *thePISeg1, *thePINod1);
2058       UpdateAroundNode (anI2p4, aNod24Indices, *theTData2, *thePISeg2, *thePINod2);
2059       theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI3, theYTI3, theZTI3,
2060                                         theX1  , theY1  , theZ1  , theX3  , theY3  , theZ3  , theIEdge,
2061                                         theI1  , theI1p1, anI1p3,  theI2  , theI2p1, anI2p3,  theFlag));
2062       theList.Prepend (HLRAlgo_BiPoint (theXTI3, theYTI3, theZTI3, theXTI4, theYTI4, theZTI4,
2063                                         theX3  , theY3  , theZ3  , theX4  , theY4  , theZ4  , theIEdge,
2064                                         theI1  , anI1p3,  anI1p4,  theI2,   anI2p3,  anI2p4,  theFlag));
2065       theList.Prepend (HLRAlgo_BiPoint (theXTI4, theYTI4, theZTI4, theXTI2, theYTI2, theZTI2,
2066                                         theX4  , theY4  , theZ4  , theX2  , theY2  , theZ2  , theIEdge,
2067                                         theI1  , anI1p4,  theI1p2, theI2  , anI2p4,  theI2p2, theFlag));
2068     }
2069   }
2070   else                                             // p1 p2
2071   {
2072     theList.Prepend (HLRAlgo_BiPoint (theXTI1, theYTI1, theZTI1, theXTI2, theYTI2, theZTI2,
2073                                       theX1  , theY1  , theZ1  , theX2  , theY2  , theZ2  , theIEdge,
2074                                       theI1  , theI1p1, theI1p2, theI2  , theI2p1, theI2p2, theFlag));
2075   }
2076 }
2077
2078 //=======================================================================
2079 //function : InsertOnOutLine
2080 //purpose  :
2081 //=======================================================================
2082 void HLRBRep_PolyAlgo::InsertOnOutLine (NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID)
2083 {
2084   HLRAlgo_Array1OfTData* aTData2 = NULL;
2085   HLRAlgo_Array1OfPISeg* aPISeg2 = NULL;
2086   HLRAlgo_Array1OfPINod* aPINod2 = NULL;
2087
2088   TopLoc_Location aLoc;
2089   Standard_Boolean mP3P1 = false;
2090   Standard_Real aU3, aV3, aCoef3, X3 = 0., Y3 = 0., Z3 = 0.;
2091
2092   const gp_Trsf& aProjTrsf = myProj.Transformation();
2093
2094   const Standard_Integer aNbFaces = myFMap.Extent();
2095   for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
2096   {
2097     const Handle(HLRAlgo_PolyInternalData)& aPid = thePID.ChangeValue (aFaceIter);
2098     if (aPid.IsNull())
2099     {
2100       continue;
2101     }
2102
2103     bool isIntOutL = Standard_False;
2104     HLRAlgo_Array1OfTData* aTData1 = &aPid->TData();
2105     HLRAlgo_Array1OfPISeg* aPISeg1 = &aPid->PISeg();
2106     HLRAlgo_Array1OfPINod* aPINod1 = &aPid->PINod();
2107     TopoDS_Shape aLocalShape = myFMap (aFaceIter);
2108     const TopoDS_Face& aFace = TopoDS::Face (aLocalShape);
2109     myBSurf.Initialize (aFace, Standard_False);
2110     myGSurf = BRep_Tool::Surface (aFace, aLoc);
2111     {
2112       gp_Trsf aTT = aLoc.Transformation();
2113       aTT.PreMultiply (aProjTrsf);
2114       const gp_XYZ& aTTrsfVec = aTT.TranslationPart();
2115       TTLo[0] = aTTrsfVec.X();
2116       TTLo[1] = aTTrsfVec.Y();
2117       TTLo[2] = aTTrsfVec.Z();
2118       const gp_Mat& aTTrsfMat = aTT.VectorialPart();
2119       TTMa[0][0] = aTTrsfMat.Value (1, 1);
2120       TTMa[0][1] = aTTrsfMat.Value (1, 2);
2121       TTMa[0][2] = aTTrsfMat.Value (1, 3);
2122       TTMa[1][0] = aTTrsfMat.Value (2, 1);
2123       TTMa[1][1] = aTTrsfMat.Value (2, 2);
2124       TTMa[1][2] = aTTrsfMat.Value (2, 3);
2125       TTMa[2][0] = aTTrsfMat.Value (3, 1);
2126       TTMa[2][1] = aTTrsfMat.Value (3, 2);
2127       TTMa[2][2] = aTTrsfMat.Value (3, 3);
2128     }
2129
2130 #ifdef OCCT_DEBUG
2131     if (DoTrace)
2132     {
2133       std::cout << " InsertOnOutLine : NbTData " << aPid->NbTData() << std::endl;
2134       std::cout << " InsertOnOutLine : NbPISeg " << aPid->NbPISeg() << std::endl;
2135       std::cout << " InsertOnOutLine : NbPINod " << aPid->NbPINod() << std::endl;
2136     }
2137 #endif
2138
2139     const Standard_Integer aNbSegs = aPid->NbPISeg();
2140     for (Standard_Integer aSegIter = 1; aSegIter <= aNbSegs; ++aSegIter)
2141     {
2142       HLRAlgo_PolyInternalSegment& aSegIndices = aPISeg1->ChangeValue (aSegIter);
2143       //        Standard_Boolean Cutted = Standard_False;
2144       if (aSegIndices.Conex1 != 0 && aSegIndices.Conex2 != 0)
2145       {
2146         const Standard_Integer ip1 = aSegIndices.LstSg1;
2147         const Standard_Integer ip2 = aSegIndices.LstSg2;
2148         const Handle(HLRAlgo_PolyInternalNode)& aPip1 = aPINod1->ChangeValue (ip1);
2149         HLRAlgo_PolyInternalNode::NodeIndices& aNod1Indices = aPip1->Indices();
2150         HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = aPip1->Data();
2151         const Handle(HLRAlgo_PolyInternalNode)& aPip2 = aPINod1->ChangeValue (ip2);
2152         HLRAlgo_PolyInternalNode::NodeIndices& aNod2Indices = aPip2->Indices();
2153         HLRAlgo_PolyInternalNode::NodeData& aNod2RValues = aPip2->Data();
2154         if (aNod1Indices.Flag & NMsk_OutL && aNod2Indices.Flag & NMsk_OutL)
2155         {
2156           isIntOutL = Standard_True;
2157         }
2158         else if ((aNod1RValues.Scal >=  myTolAngular &&
2159                   aNod2RValues.Scal <= -myTolAngular) ||
2160                   (aNod2RValues.Scal >=  myTolAngular &&
2161                   aNod1RValues.Scal <= -myTolAngular))
2162         {
2163           isIntOutL = Standard_True;
2164           bool isInsP3 = NewNode (aNod1RValues, aNod2RValues, aCoef3, mP3P1);
2165           if (isInsP3)
2166           {
2167             UVNode (aNod1RValues, aNod2RValues, aCoef3, aU3, aV3);
2168             if (!myGSurf.IsNull())
2169             {
2170               const gp_Pnt aPT3 = myGSurf->Value (aU3, aV3);
2171               X3 = aPT3.X();
2172               Y3 = aPT3.Y();
2173               Z3 = aPT3.Z();
2174             }
2175             else
2176             {
2177               // simple averaging - this could be improved
2178               const Standard_Real aCoef2 = 1.0 - aCoef3;
2179               const gp_Pnt aPT3 = aCoef2 * aNod1RValues.Point + aCoef3 * aNod2RValues.Point;
2180               X3 = aPT3.X();
2181               Y3 = aPT3.Y();
2182               Z3 = aPT3.Z();
2183             }
2184             TTMultiply (X3, Y3, Z3);
2185           }
2186
2187           if (isInsP3 && mP3P1)                         // P1 ---> P3
2188           {
2189             if ((aNod1Indices.Flag & NMsk_Edge) == 0 && aCoef3 < myTolSta)
2190             {
2191               isInsP3 = Standard_False;
2192               ChangeNode (ip1, ip2,
2193                           aNod1Indices, aNod1RValues,
2194                           aNod2Indices, aNod2RValues,
2195                           aCoef3, X3, Y3, Z3, Standard_True,
2196                           *aTData1, *aPISeg1, *aPINod1);
2197               aNod1RValues.Scal  = 0;
2198               aNod1Indices.Flag |= NMsk_OutL;
2199             }
2200           }
2201           if (isInsP3 && !mP3P1)                        // P2 ---> P3
2202           {
2203             if ((aNod2Indices.Flag & NMsk_Edge) == 0 && aCoef3 > myTolEnd)
2204             {
2205               isInsP3 = Standard_False;
2206               ChangeNode (ip1, ip2,
2207                           aNod1Indices, aNod1RValues,
2208                           aNod2Indices, aNod2RValues,
2209                           aCoef3, X3, Y3, Z3, Standard_False,
2210                           *aTData1, *aPISeg1, *aPINod1);
2211               aNod2RValues.Scal  = 0;
2212               aNod2Indices.Flag |= NMsk_OutL;
2213             }
2214           }
2215           if (isInsP3)                                  // p1 ip3 p2
2216           {
2217             const Standard_Integer ip3 = aPid->AddNode (aNod1RValues, aNod2RValues, aPINod1, aPINod2,
2218                                                         aCoef3, X3, Y3, Z3);
2219             const Handle(HLRAlgo_PolyInternalNode)& aPip3 = aPINod1->ChangeValue(ip3);
2220             HLRAlgo_PolyInternalNode::NodeIndices& aNod3Indices = aPip3->Indices();
2221             HLRAlgo_PolyInternalNode::NodeData& aNod3RValues = aPip3->Data();
2222             aPid->UpdateLinks (ip1, ip2, ip3,
2223                                aTData1, aTData2, aPISeg1, aPISeg2, aPINod1, aPINod2);
2224             UpdateAroundNode (ip3, aNod3Indices, *aTData1, *aPISeg1, *aPINod1);
2225             aNod3RValues.Scal  = 0;
2226             aNod3Indices.Flag |= NMsk_OutL;
2227           }
2228         }
2229       }
2230     }
2231     if (isIntOutL)
2232     {
2233       aPid->IntOutL (Standard_True);
2234     }
2235
2236 #ifdef OCCT_DEBUG
2237     if (DoTrace)
2238     {
2239       std::cout << " InsertOnOutLine : NbTData " << aPid->NbTData() << std::endl;
2240       std::cout << " InsertOnOutLine : NbPISeg " << aPid->NbPISeg() << std::endl;
2241       std::cout << " InsertOnOutLine : NbPINod " << aPid->NbPINod() << std::endl;
2242     }
2243 #endif
2244   }
2245 }
2246
2247 //=======================================================================
2248 //function : CheckFrBackTriangles
2249 //purpose  :
2250 //=======================================================================
2251 void HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& theList,
2252                                              NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID)
2253 {
2254   Standard_Real X1 =0.,Y1 =0.,X2 =0.,Y2 =0.,X3 =0.,Y3 =0.;
2255   Standard_Real D1,D2,D3;
2256   Standard_Real dd,dX,dY,nX,nY;
2257
2258   HLRAlgo_Array1OfTData* aTData1 = NULL;
2259   HLRAlgo_Array1OfPISeg* aPISeg1 = NULL;
2260   HLRAlgo_Array1OfPINod* aPINod1 = NULL;
2261   HLRAlgo_Array1OfTData* aTData2 = NULL;
2262   HLRAlgo_Array1OfPISeg* aPISeg2 = NULL;
2263   HLRAlgo_Array1OfPINod* aPINod2 = NULL;
2264
2265   const Standard_Integer aNbFaces = myFMap.Extent();
2266   Standard_Boolean isModif = Standard_True;
2267   Standard_Integer iLoop = 0;
2268   
2269   while (isModif && iLoop < 4)
2270   {
2271     iLoop++;
2272     isModif = false;
2273     bool isFrBackInList = false;
2274     for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
2275     {
2276       const Handle(HLRAlgo_PolyInternalData)& pid = thePID.ChangeValue (aFaceIter);
2277       if (pid.IsNull())
2278       {
2279         continue;
2280       }
2281
2282       const Standard_Integer aNbTris = pid->NbTData();
2283       HLRAlgo_Array1OfTData* aTData = &pid->TData();
2284       HLRAlgo_Array1OfPISeg* aPISeg = &pid->PISeg();
2285       HLRAlgo_Array1OfPINod* aPINod = &pid->PINod();
2286       for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
2287       {
2288         HLRAlgo_TriangleData* tdata = &aTData->ChangeValue (aTriIter);
2289         if ((tdata->Flags & HLRAlgo_PolyMask_FMskSide) == 0 &&
2290             (tdata->Flags & HLRAlgo_PolyMask_FMskFrBack))
2291         {
2292         #ifdef OCCT_DEBUG
2293           if (DoTrace)
2294           {
2295             std::cout << " face : " << aFaceIter << " , triangle " << aTriIter << std::endl;
2296           }
2297         #endif
2298           isModif = Standard_True;
2299           const Handle(HLRAlgo_PolyInternalNode)* pi1p1 = &aPINod->ChangeValue (tdata->Node1);
2300           HLRAlgo_PolyInternalNode::NodeIndices* aNod11Indices = &(*pi1p1)->Indices();
2301           HLRAlgo_PolyInternalNode::NodeData* aNod11RValues = &(*pi1p1)->Data();
2302           const Handle(HLRAlgo_PolyInternalNode)* pi1p2 = &aPINod->ChangeValue (tdata->Node2);
2303           HLRAlgo_PolyInternalNode::NodeIndices* aNod12Indices = &(*pi1p2)->Indices();
2304           HLRAlgo_PolyInternalNode::NodeData* aNod12RValues = &(*pi1p2)->Data();
2305           const Handle(HLRAlgo_PolyInternalNode)* pi1p3 = &aPINod->ChangeValue (tdata->Node3);
2306           HLRAlgo_PolyInternalNode::NodeIndices* aNod13Indices = &(*pi1p3)->Indices();
2307           HLRAlgo_PolyInternalNode::NodeData* aNod13RValues = &(*pi1p3)->Data();
2308           D1 = 0.; D2 = 0.; D3 = 0.;
2309           if (((aNod11Indices->Flag & NMsk_Edge) == 0 || iLoop > 1) &&
2310               ((aNod11Indices->Flag & NMsk_OutL) == 0 || iLoop > 1) &&
2311               ((aNod11Indices->Flag & NMsk_Vert) == 0))
2312           {
2313             dX = aNod13RValues->Point.X() - aNod12RValues->Point.X();
2314             dY = aNod13RValues->Point.Y() - aNod12RValues->Point.Y();
2315             D1 = dX * dX + dY * dY;
2316             D1 = sqrt(D1);
2317             nX = - dY / D1; nY =   dX / D1;
2318             dX = aNod11RValues->Point.X() - aNod12RValues->Point.X();
2319             dY = aNod11RValues->Point.Y() - aNod12RValues->Point.Y();
2320             dd = - (dX * nX + dY * nY);
2321             if (dd < 0) { dd -= D1 * 0.01; }
2322             else        { dd += D1 * 0.01; }
2323             X1 = nX * dd; Y1 = nY * dd;
2324           }
2325           if (((aNod12Indices->Flag & NMsk_Edge) == 0 || iLoop > 1) &&
2326               ((aNod12Indices->Flag & NMsk_OutL) == 0 || iLoop > 1) &&
2327               ((aNod12Indices->Flag & NMsk_Vert) == 0))
2328           {
2329             dX = aNod11RValues->Point.X() - aNod13RValues->Point.X();
2330             dY = aNod11RValues->Point.Y() - aNod13RValues->Point.Y();
2331             D2 = dX * dX + dY * dY;
2332             D2 = sqrt(D2);
2333             nX = - dY / D2; nY =   dX / D2;
2334             dX = aNod12RValues->Point.X() - aNod13RValues->Point.X();
2335             dY = aNod12RValues->Point.Y() - aNod13RValues->Point.Y();
2336             dd = - (dX * nX + dY * nY);
2337             if (dd < 0) { dd -= D2 * 0.01; }
2338             else        { dd += D2 * 0.01; }
2339             X2 = nX * dd; Y2 = nY * dd;
2340           }
2341           if (((aNod13Indices->Flag & NMsk_Edge) == 0 || iLoop > 1) &&
2342               ((aNod13Indices->Flag & NMsk_OutL) == 0 || iLoop > 1) &&
2343               ((aNod13Indices->Flag & NMsk_Vert) == 0))
2344           {
2345             dX = aNod12RValues->Point.X() - aNod11RValues->Point.X();
2346             dY = aNod12RValues->Point.Y() - aNod11RValues->Point.Y();
2347             D3 = dX * dX + dY * dY;
2348             D3 = sqrt(D3);
2349             nX = - dY / D3; nY =   dX / D3;
2350             dX = aNod13RValues->Point.X() - aNod11RValues->Point.X();
2351             dY = aNod13RValues->Point.Y() - aNod11RValues->Point.Y();
2352             dd = - (dX * nX + dY * nY);
2353             if (dd < 0) { dd -= D3 * 0.01; }
2354             else        { dd += D3 * 0.01; }
2355             X3 = nX * dd; Y3 = nY * dd;
2356           }
2357           if      (D1 > D2 && D1 > D3)
2358           {
2359             aNod11RValues->Point.ChangeCoord(1) += X1;
2360             aNod11RValues->Point.ChangeCoord(2) += Y1;
2361             aNod11Indices->Flag |= NMsk_Move;
2362             UpdateAroundNode (tdata->Node1, *aNod11Indices, *aTData, *aPISeg, *aPINod);
2363             isFrBackInList = Standard_True;
2364           #ifdef OCCT_DEBUG
2365             if (DoTrace)
2366             {
2367               std::cout << tdata->Node1 << " modifies  : DX,DY ";
2368               std::cout << X1 << " , " << Y1 << std::endl;
2369             }
2370           #endif
2371           }
2372           else if (D2 > D3 && D2 > D1)
2373           {
2374             aNod12RValues->Point.ChangeCoord(1) += X2;
2375             aNod12RValues->Point.ChangeCoord(2) += Y2;
2376             aNod12Indices->Flag |= NMsk_Move;
2377             UpdateAroundNode (tdata->Node2, *aNod12Indices, *aTData, *aPISeg, *aPINod);
2378             isFrBackInList = Standard_True;
2379           #ifdef OCCT_DEBUG
2380             if (DoTrace)
2381             {
2382               std::cout << tdata->Node2 << " modifies  : DX,DY ";
2383               std::cout << X2 << " , " << Y2 << std::endl;
2384             }
2385           #endif
2386           }
2387           else if (D3 > D1 && D3 > D2)
2388           {
2389             aNod13RValues->Point.ChangeCoord(1) += X3;
2390             aNod13RValues->Point.ChangeCoord(2) += Y3;
2391             aNod13Indices->Flag |= NMsk_Move;
2392             UpdateAroundNode (tdata->Node3, *aNod13Indices, *aTData, *aPISeg, *aPINod);
2393             isFrBackInList = Standard_True;
2394           #ifdef OCCT_DEBUG
2395             if (DoTrace)
2396             {
2397               std::cout << tdata->Node3 << " modifies  : DX,DY ";
2398               std::cout << X3 << " , " << Y3 << std::endl;
2399             }
2400           #endif
2401           }
2402         #ifdef OCCT_DEBUG
2403           else if (DoTrace)
2404           {
2405             std::cout << "modification error" << std::endl;
2406           }
2407         #endif
2408         }
2409       }
2410     }
2411     if (isFrBackInList)
2412     {
2413       for (HLRAlgo_ListIteratorOfListOfBPoint aBPointIter (theList); aBPointIter.More(); aBPointIter.Next())
2414       {
2415         HLRAlgo_BiPoint& BP = aBPointIter.ChangeValue();
2416         HLRAlgo_BiPoint::IndicesT& theIndices = BP.Indices();
2417         if (theIndices.FaceConex1 != 0)
2418         {
2419           const Handle(HLRAlgo_PolyInternalData)& pid1 = thePID.Value (theIndices.FaceConex1);
2420           aTData1 = &pid1->TData();
2421           aPISeg1 = &pid1->PISeg();
2422           aPINod1 = &pid1->PINod();
2423         }
2424         if (theIndices.FaceConex2 != 0)
2425         {
2426           if (theIndices.FaceConex1 == theIndices.FaceConex2)
2427           {
2428             aTData2 = aTData1;
2429             aPISeg2 = aPISeg1;
2430             aPINod2 = aPINod1;
2431           }
2432           else
2433           {
2434             const Handle(HLRAlgo_PolyInternalData)& pid2 = thePID.Value (theIndices.FaceConex2);
2435             aTData2 = &pid2->TData();
2436             aPISeg2 = &pid2->PISeg();
2437             aPINod2 = &pid2->PINod();
2438           }
2439         }
2440         if (theIndices.FaceConex1 != 0)
2441         {
2442           HLRAlgo_PolyInternalNode::NodeIndices* aNod11Indices = &aPINod1->ChangeValue (theIndices.Face1Pt1)->Indices();
2443           if (aNod11Indices->Flag & NMsk_Move)
2444           {
2445           #ifdef OCCT_DEBUG
2446             if (DoTrace)
2447             {
2448               std::cout << theIndices.Face1Pt1 << " modifies 11" << std::endl;
2449             }
2450           #endif
2451             const HLRAlgo_PolyInternalNode::NodeData& aNod11RValues = aPINod1->Value (theIndices.Face1Pt1)->Data();
2452             HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
2453             aPoints.Pnt1 = aPoints.PntP1 = aNod11RValues.Point;
2454             TIMultiply (aPoints.Pnt1);
2455             if (theIndices.FaceConex2 != 0)
2456             {
2457               HLRAlgo_PolyInternalNode::NodeIndices& aNod12Indices = aPINod2->ChangeValue (theIndices.Face2Pt1)->Indices();
2458               HLRAlgo_PolyInternalNode::NodeData& aNod12RValues = aPINod2->ChangeValue (theIndices.Face2Pt1)->Data();
2459               aNod12RValues.Point.ChangeCoord(1) = aNod11RValues.Point.X();
2460               aNod12RValues.Point.ChangeCoord(2) = aNod11RValues.Point.Y();
2461               UpdateAroundNode (theIndices.Face2Pt1, aNod12Indices,
2462                                 *aTData2, *aPISeg2, *aPINod2);
2463             }
2464           }
2465           aNod11Indices = &aPINod1->ChangeValue (theIndices.Face1Pt2)->Indices();
2466           if (aNod11Indices->Flag & NMsk_Move)
2467           {
2468           #ifdef OCCT_DEBUG
2469             if (DoTrace)
2470             {
2471               std::cout << theIndices.Face1Pt2 << " modifies 12" << std::endl;
2472             }
2473           #endif
2474             const HLRAlgo_PolyInternalNode::NodeData& aNod11RValues = aPINod1->Value (theIndices.Face1Pt2)->Data();
2475             HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
2476             aPoints.Pnt2 = aPoints.PntP2 = aNod11RValues.Point;
2477             TIMultiply(aPoints.Pnt2);
2478             if (theIndices.FaceConex2 != 0)
2479             {
2480               HLRAlgo_PolyInternalNode::NodeIndices& aNod12Indices = aPINod2->ChangeValue (theIndices.Face2Pt2)->Indices();
2481               HLRAlgo_PolyInternalNode::NodeData& aNod12RValues = aPINod2->ChangeValue (theIndices.Face2Pt2)->Data();
2482               aNod12RValues.Point.ChangeCoord(1) = aNod11RValues.Point.X();
2483               aNod12RValues.Point.ChangeCoord(2) = aNod11RValues.Point.Y();
2484               UpdateAroundNode (theIndices.Face2Pt2, aNod12Indices,
2485                                 *aTData2, *aPISeg2, *aPINod2);
2486             }
2487           }
2488         }
2489         if (theIndices.FaceConex2 != 0)
2490         {
2491           const Handle(HLRAlgo_PolyInternalData)& pid2 = thePID.Value (theIndices.FaceConex2);
2492           aPINod2 = &pid2->PINod();
2493           HLRAlgo_PolyInternalNode::NodeIndices* aNod11Indices = &aPINod2->ChangeValue (theIndices.Face2Pt1)->Indices();
2494           if (aNod11Indices->Flag & NMsk_Move)
2495           {
2496           #ifdef OCCT_DEBUG
2497             if (DoTrace)
2498             {
2499               std::cout << theIndices.Face2Pt1 << " modifies 21" << std::endl;
2500             }
2501           #endif
2502             const HLRAlgo_PolyInternalNode::NodeData& aNod11RValues = aPINod2->Value (theIndices.Face2Pt1)->Data();
2503             HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
2504             aPoints.Pnt1 = aPoints.PntP1 = aNod11RValues.Point;
2505             TIMultiply(aPoints.Pnt1);
2506             if (theIndices.FaceConex1 != 0)
2507             {
2508               HLRAlgo_PolyInternalNode::NodeIndices& aNod12Indices = aPINod1->ChangeValue (theIndices.Face1Pt1)->Indices();
2509               HLRAlgo_PolyInternalNode::NodeData& aNod12RValues = aPINod1->ChangeValue (theIndices.Face1Pt1)->Data();
2510               aNod12RValues.Point.ChangeCoord(1) = aNod11RValues.Point.X();
2511               aNod12RValues.Point.ChangeCoord(2) = aNod11RValues.Point.Y();
2512               UpdateAroundNode (theIndices.Face1Pt1, aNod12Indices,
2513                                 *aTData1, *aPISeg1, *aPINod1);
2514             }
2515           }
2516           aNod11Indices = &aPINod2->ChangeValue (theIndices.Face2Pt2)->Indices();
2517           if (aNod11Indices->Flag & NMsk_Move)
2518           {
2519           #ifdef OCCT_DEBUG
2520             if (DoTrace)
2521             {
2522               std::cout << theIndices.Face2Pt2 << " modifies 22" << std::endl;
2523             }
2524           #endif
2525             const HLRAlgo_PolyInternalNode::NodeData* aNod11RValues = &aPINod2->Value (theIndices.Face2Pt2)->Data();
2526             HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
2527             aPoints.Pnt2 = aPoints.PntP2 = aNod11RValues->Point;
2528             TIMultiply (aPoints.Pnt2);
2529             if (theIndices.FaceConex1 != 0)
2530             {
2531               HLRAlgo_PolyInternalNode::NodeIndices& aNod12Indices = aPINod1->ChangeValue (theIndices.Face1Pt2)->Indices();
2532               HLRAlgo_PolyInternalNode::NodeData& aNod12RValues = aPINod1->ChangeValue (theIndices.Face1Pt2)->Data();
2533               aNod12RValues.Point.ChangeCoord(1) = aNod11RValues->Point.X();
2534               aNod12RValues.Point.ChangeCoord(2) = aNod11RValues->Point.Y();
2535               UpdateAroundNode (theIndices.Face1Pt2, aNod12Indices,
2536                                 *aTData1, *aPISeg1, *aPINod1);
2537             }
2538           }
2539         }
2540       }
2541
2542       for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
2543       {
2544         const Handle(HLRAlgo_PolyInternalData)& aPid = thePID.ChangeValue (aFaceIter);
2545         if (!aPid.IsNull())
2546         {
2547           const Standard_Integer aNbNodes = aPid->NbPINod();
2548           HLRAlgo_Array1OfPINod& aPINod = aPid->PINod();
2549           for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
2550           {
2551             HLRAlgo_PolyInternalNode::NodeIndices& aNod11Indices = aPINod.ChangeValue (aNodeIter)->Indices();
2552             aNod11Indices.Flag &= ~NMsk_Move;
2553           }
2554         }
2555       }
2556     }
2557   }
2558 }
2559
2560 //=======================================================================
2561 //function : FindEdgeOnTriangle
2562 //purpose  :
2563 //=======================================================================
2564 void HLRBRep_PolyAlgo::FindEdgeOnTriangle (const HLRAlgo_TriangleData& theTriangle,
2565                                            const Standard_Integer theIp1,
2566                                            const Standard_Integer theIp2,
2567                                            Standard_Integer& theJtrouv,
2568                                            Standard_Boolean& theIsDirect) const
2569 {
2570   Standard_Integer n1 = theTriangle.Node1;
2571   Standard_Integer n2 = theTriangle.Node2;
2572   Standard_Integer n3 = theTriangle.Node3;
2573   if      (theIp1 == n1 && theIp2 == n2)
2574   {
2575     theJtrouv = 0;
2576     theIsDirect = Standard_True;
2577     return;
2578   }
2579   else if (theIp2 == n1 && theIp1 == n2)
2580   {
2581     theJtrouv = 0;
2582     theIsDirect = Standard_False;
2583     return;
2584   }
2585   else if (theIp1 == n2 && theIp2 == n3)
2586   {
2587     theJtrouv = 1;
2588     theIsDirect = Standard_True;
2589     return;
2590   }
2591   else if (theIp2 == n2 && theIp1 == n3)
2592   {
2593     theJtrouv = 1;
2594     theIsDirect = Standard_False;
2595     return;
2596   }
2597   else if (theIp1 == n3 && theIp2 == n1)
2598   {
2599     theJtrouv = 2;
2600     theIsDirect = Standard_True;
2601     return;
2602   }
2603   else if (theIp2 == n3 && theIp1 == n1)
2604   {
2605     theJtrouv = 2;
2606     theIsDirect = Standard_False;
2607     return;
2608   }
2609 }
2610
2611 //=======================================================================
2612 //function : ChangeNode
2613 //purpose  :
2614 //=======================================================================
2615 void HLRBRep_PolyAlgo::ChangeNode (const Standard_Integer theIp1,
2616                                    const Standard_Integer theIp2,
2617                                    HLRAlgo_PolyInternalNode::NodeIndices& theNod1Indices,
2618                                    HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
2619                                    HLRAlgo_PolyInternalNode::NodeIndices& theNod2Indices,
2620                                    HLRAlgo_PolyInternalNode::NodeData& theNod2RValues,
2621                                    const Standard_Real theCoef1,
2622                                    const Standard_Real theX3,
2623                                    const Standard_Real theY3,
2624                                    const Standard_Real theZ3,
2625                                    const Standard_Boolean theIsFirst,
2626                                    HLRAlgo_Array1OfTData& theTData,
2627                                    HLRAlgo_Array1OfPISeg& thePISeg,
2628                                    HLRAlgo_Array1OfPINod& thePINod) const
2629 {
2630   const Standard_Real aCoef2 = 1.0 - theCoef1;
2631   if (theIsFirst)
2632   {
2633     theNod1RValues.Point = gp_XYZ (theX3, theY3, theZ3);
2634     theNod1RValues.UV = aCoef2 * theNod1RValues.UV + theCoef1 * theNod2RValues.UV;
2635     theNod1RValues.Scal = theNod1RValues.Scal * aCoef2 + theNod2RValues.Scal * theCoef1;
2636     const gp_XYZ aXYZ = aCoef2 * theNod1RValues.Normal + theCoef1 * theNod2RValues.Normal;
2637     const Standard_Real aNorm = aXYZ.Modulus();
2638     if (aNorm > 0)
2639     {
2640       theNod1RValues.Normal = (1 / aNorm) * aXYZ;
2641     }
2642     else
2643     {
2644       theNod1RValues.Normal = gp_XYZ(1., 0., 0.);
2645 #ifdef OCCT_DEBUG
2646       if (DoError)
2647       {
2648         std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << theIp1;
2649         std::cout << " and " << theIp2 << std::endl;
2650       }
2651 #endif
2652     }
2653     UpdateAroundNode (theIp1, theNod1Indices, theTData, thePISeg, thePINod);
2654   }
2655   else
2656   {
2657     theNod2RValues.Point = gp_XYZ (theX3, theY3, theZ3);
2658     theNod2RValues.UV = aCoef2 * theNod1RValues.UV + theCoef1 * theNod2RValues.UV;
2659     theNod2RValues.Scal = theNod1RValues.Scal * aCoef2 + theNod2RValues.Scal * theCoef1;
2660     const gp_XYZ aXYZ = aCoef2 * theNod1RValues.Normal + theCoef1 * theNod2RValues.Normal;
2661     const Standard_Real aNorm = aXYZ.Modulus();
2662     if (aNorm > 0)
2663     {
2664       theNod2RValues.Normal = (1 / aNorm) * aXYZ;
2665     }
2666     else
2667     {
2668       theNod2RValues.Normal = gp_XYZ(1., 0., 0.);
2669 #ifdef OCCT_DEBUG
2670       if (DoError)
2671       {
2672         std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << theIp2;
2673         std::cout << " and " << theIp1 << std::endl;
2674       }
2675 #endif
2676     }
2677     UpdateAroundNode (theIp2, theNod2Indices, theTData, thePISeg, thePINod);
2678   }
2679 }
2680
2681 //=======================================================================
2682 //function : UpdateAroundNode
2683 //purpose  :
2684 //=======================================================================
2685 void HLRBRep_PolyAlgo::UpdateAroundNode (const Standard_Integer theINode,
2686                                          HLRAlgo_PolyInternalNode::NodeIndices& theNod1Indices,
2687                                          HLRAlgo_Array1OfTData& theTData,
2688                                          HLRAlgo_Array1OfPISeg& thePISeg,
2689                                          HLRAlgo_Array1OfPINod& thePINod) const
2690 {
2691   Standard_Integer iiii = theNod1Indices.NdSg;
2692   while (iiii != 0)
2693   {
2694     HLRAlgo_PolyInternalSegment& aSegIndices = thePISeg.ChangeValue (iiii);
2695     const Standard_Integer iTri1 = aSegIndices.Conex1;
2696     const Standard_Integer iTri2 = aSegIndices.Conex2;
2697     if (iTri1 != 0)
2698     {
2699       HLRAlgo_TriangleData& aTriangle = theTData.ChangeValue (iTri1);
2700       const Handle(HLRAlgo_PolyInternalNode)& aPN1 = thePINod.ChangeValue (aTriangle.Node1);
2701       const Handle(HLRAlgo_PolyInternalNode)& aPN2 = thePINod.ChangeValue (aTriangle.Node2);
2702       const Handle(HLRAlgo_PolyInternalNode)& aPN3 = thePINod.ChangeValue (aTriangle.Node3);
2703       HLRAlgo_PolyInternalNode::NodeIndices& aNod1Indices = aPN1->Indices();
2704       HLRAlgo_PolyInternalNode::NodeIndices& aNod2Indices = aPN2->Indices();
2705       HLRAlgo_PolyInternalNode::NodeIndices& aNod3Indices = aPN3->Indices();
2706       HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = aPN1->Data();
2707       HLRAlgo_PolyInternalNode::NodeData& aNod2RValues = aPN2->Data();
2708       HLRAlgo_PolyInternalNode::NodeData& aNod3RValues = aPN3->Data();
2709       OrientTriangle (iTri1, aTriangle,
2710                       aNod1Indices, aNod1RValues,
2711                       aNod2Indices, aNod2RValues,
2712                       aNod3Indices, aNod3RValues);
2713     }
2714     if (iTri2 != 0)
2715     {
2716       HLRAlgo_TriangleData& aTriangle2 = theTData.ChangeValue (iTri2);
2717       const Handle(HLRAlgo_PolyInternalNode)& aPN1 = thePINod.ChangeValue (aTriangle2.Node1);
2718       const Handle(HLRAlgo_PolyInternalNode)& aPN2 = thePINod.ChangeValue (aTriangle2.Node2);
2719       const Handle(HLRAlgo_PolyInternalNode)& aPN3 = thePINod.ChangeValue (aTriangle2.Node3);
2720       HLRAlgo_PolyInternalNode::NodeIndices& aNod1Indices = aPN1->Indices();
2721       HLRAlgo_PolyInternalNode::NodeIndices& aNod2Indices = aPN2->Indices();
2722       HLRAlgo_PolyInternalNode::NodeIndices& aNod3Indices = aPN3->Indices();
2723       HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = aPN1->Data();
2724       HLRAlgo_PolyInternalNode::NodeData& aNod2RValues = aPN2->Data();
2725       HLRAlgo_PolyInternalNode::NodeData& aNod3RValues = aPN3->Data();
2726       OrientTriangle (iTri2, aTriangle2,
2727                       aNod1Indices, aNod1RValues,
2728                       aNod2Indices, aNod2RValues,
2729                       aNod3Indices, aNod3RValues);
2730     }
2731     if (aSegIndices.LstSg1 == theINode) { iiii = aSegIndices.NxtSg1; }
2732     else                                { iiii = aSegIndices.NxtSg2; }
2733   }
2734 }
2735
2736 //=======================================================================
2737 //function : OrientTriangle
2738 //purpose  :
2739 //=======================================================================
2740 void  HLRBRep_PolyAlgo::OrientTriangle (const Standard_Integer theITri,
2741                                         HLRAlgo_TriangleData& theTriangle,
2742                                         HLRAlgo_PolyInternalNode::NodeIndices& theNod1Indices,
2743                                         HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
2744                                         HLRAlgo_PolyInternalNode::NodeIndices& theNod2Indices,
2745                                         HLRAlgo_PolyInternalNode::NodeData& theNod2RValues,
2746                                         HLRAlgo_PolyInternalNode::NodeIndices& theNod3Indices,
2747                                         HLRAlgo_PolyInternalNode::NodeData& theNod3RValues) const
2748 {
2749   Standard_Boolean o1 = (theNod1Indices.Flag & NMsk_OutL) != 0;
2750   Standard_Boolean o2 = (theNod2Indices.Flag & NMsk_OutL) != 0;
2751   Standard_Boolean o3 = (theNod3Indices.Flag & NMsk_OutL) != 0;
2752   theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskFlat;
2753   theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskOnOutL;
2754   if (o1 && o2 && o3)
2755   {
2756     theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2757     theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2758     theTriangle.Flags |=  HLRAlgo_PolyMask_FMskOnOutL;
2759 #ifdef OCCT_DEBUG
2760     if (DoTrace)
2761     {
2762       std::cout << "HLRBRep_PolyAlgo::OrientTriangle : OnOutL";
2763       std::cout << " triangle " << theITri << std::endl;
2764     }
2765 #else
2766     (void )theITri;
2767 #endif
2768   }
2769   else
2770   {
2771     const Standard_Real s1 = theNod1RValues.Scal;
2772     const Standard_Real s2 = theNod2RValues.Scal;
2773     const Standard_Real s3 = theNod3RValues.Scal;
2774     Standard_Real as1 = s1;
2775     Standard_Real as2 = s2;
2776     Standard_Real as3 = s3;
2777     if (s1 < 0) { as1 = -s1; }
2778     if (s2 < 0) { as2 = -s2; }
2779     if (s3 < 0) { as3 = -s3; }
2780     Standard_Real  s = 0;
2781     Standard_Real as = 0;
2782     if (!o1            ) {s = s1; as = as1;}
2783     if (!o2 && as < as2) {s = s2; as = as2;}
2784     if (!o3 && as < as3) {s = s3; as = as3;}
2785     if (s > 0)
2786     {
2787       theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskSide;
2788       theTriangle.Flags |=  HLRAlgo_PolyMask_FMskBack;
2789     }
2790     else
2791     {
2792       theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskSide;
2793       theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2794     }
2795     gp_XYZ aD12 = theNod2RValues.Point - theNod1RValues.Point;
2796     const Standard_Real aD12Norm = aD12.Modulus();
2797     if (aD12Norm <= 1.e-10)
2798     {
2799 #ifdef OCCT_DEBUG
2800       if (DoTrace)
2801       {
2802         std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
2803         std::cout << " triangle " << theITri << std::endl;
2804       }
2805 #endif
2806       theTriangle.Flags |=  HLRAlgo_PolyMask_FMskFlat;
2807       theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2808       theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2809     }
2810     else
2811     {
2812       gp_XYZ aD23 = theNod3RValues.Point - theNod2RValues.Point;
2813       const Standard_Real aD23Norm = aD23.Modulus();
2814       if (aD23Norm < 1.e-10)
2815       {
2816       #ifdef OCCT_DEBUG
2817         if (DoTrace)
2818         {
2819           std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
2820           std::cout << " triangle " << theITri << std::endl;
2821         }
2822       #endif
2823         theTriangle.Flags |=  HLRAlgo_PolyMask_FMskFlat;
2824         theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2825         theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2826       }
2827       else
2828       {
2829         const gp_XYZ aD31 = theNod1RValues.Point - theNod3RValues.Point;
2830         const Standard_Real aD31Norm = aD31.Modulus();
2831         if (aD31Norm < 1.e-10)
2832         {
2833         #ifdef OCCT_DEBUG
2834           if (DoTrace)
2835           {
2836             std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
2837             std::cout << " triangle " << theITri << std::endl;
2838           }
2839         #endif
2840           theTriangle.Flags |=  HLRAlgo_PolyMask_FMskFlat;
2841           theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2842           theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2843         }
2844         else
2845         {
2846           aD12 *= 1 / aD12Norm;
2847           aD23 *= 1 / aD23Norm;
2848           gp_XYZ aD = aD12 ^ aD23;
2849           const Standard_Real aDNorm = aD.Modulus();
2850           if (aDNorm < 1.e-5)
2851           {
2852           #ifdef OCCT_DEBUG
2853             if (DoTrace)
2854             {
2855               std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
2856               std::cout << " triangle " << theITri << std::endl;
2857             }
2858           #endif
2859             theTriangle.Flags |=  HLRAlgo_PolyMask_FMskFlat;
2860             theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2861             theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2862           }
2863           else
2864           {
2865             Standard_Real o;
2866             if (myProj.Perspective())
2867             {
2868               aD *= 1 / aDNorm;
2869               o = aD.Z() * myProj.Focus() - aD * theNod1RValues.Point;
2870             }
2871             else
2872             {
2873               o = aD.Z() / aDNorm;
2874             }
2875             if (o < 0)
2876             {
2877               theTriangle.Flags |=  HLRAlgo_PolyMask_FMskOrBack;
2878               o = -o;
2879             }
2880             else
2881             {
2882               theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskOrBack;
2883             }
2884             if (o < 1.e-10)
2885             {
2886               theTriangle.Flags |=  HLRAlgo_PolyMask_FMskSide;
2887               theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskBack;
2888             }
2889           }
2890         }
2891       }
2892     }
2893   }
2894
2895   if ((!(theTriangle.Flags & HLRAlgo_PolyMask_FMskBack) &&  (theTriangle.Flags & HLRAlgo_PolyMask_FMskOrBack)) ||
2896       ( (theTriangle.Flags & HLRAlgo_PolyMask_FMskBack) && !(theTriangle.Flags & HLRAlgo_PolyMask_FMskOrBack)))
2897   {
2898     theTriangle.Flags |=  HLRAlgo_PolyMask_FMskFrBack;
2899   }
2900   else 
2901   {
2902     theTriangle.Flags &= ~HLRAlgo_PolyMask_FMskFrBack;
2903   }
2904 }
2905
2906 //=======================================================================
2907 //function : Triangles
2908 //purpose  :
2909 //=======================================================================
2910 Standard_Boolean HLRBRep_PolyAlgo::Triangles (const Standard_Integer theIp1,
2911                                               const Standard_Integer theIp2,
2912                                               HLRAlgo_PolyInternalNode::NodeIndices& theNod1Indices,
2913                                               HLRAlgo_Array1OfPISeg*& thePISeg,
2914                                               Standard_Integer& theITri1,
2915                                               Standard_Integer& theITri2) const
2916 {
2917   Standard_Integer iiii = theNod1Indices.NdSg;
2918   while (iiii != 0)
2919   {
2920     HLRAlgo_PolyInternalSegment& aSegIndices = thePISeg->ChangeValue (iiii);
2921     if (aSegIndices.LstSg1 == theIp1)
2922     {
2923       if (aSegIndices.LstSg2 == theIp2)
2924       {
2925         theITri1 = aSegIndices.Conex1;
2926         theITri2 = aSegIndices.Conex2;
2927         return Standard_True;
2928       }
2929       else
2930       {
2931         iiii = aSegIndices.NxtSg1;
2932       }
2933     }
2934     else
2935     {
2936       if (aSegIndices.LstSg1 == theIp2)
2937       {
2938         theITri1 = aSegIndices.Conex1;
2939         theITri2 = aSegIndices.Conex2;
2940         return Standard_True;
2941       }
2942       else
2943       {
2944         iiii = aSegIndices.NxtSg2;
2945       }
2946     }
2947   }
2948   theITri1 = 0;
2949   theITri2 = 0;
2950 #ifdef OCCT_DEBUG
2951   if (DoError)
2952   {
2953     std::cout << "HLRBRep_PolyAlgo::Triangles : error";
2954     std::cout << " between " << theIp1 << " and " << theIp2 << std::endl;
2955   }
2956 #endif
2957   return Standard_False;
2958 }
2959
2960 //=======================================================================
2961 //function : NewNode
2962 //purpose  :
2963 //=======================================================================
2964 Standard_Boolean HLRBRep_PolyAlgo::NewNode (HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
2965                                             HLRAlgo_PolyInternalNode::NodeData& theNod2RValues,
2966                                             Standard_Real& theCoef1,
2967                                             Standard_Boolean& theToMoveP1) const
2968 {
2969   const Standard_Real aTolAng = myTolAngular * 0.5;
2970   if ((theNod1RValues.Scal >= aTolAng && theNod2RValues.Scal <= -aTolAng) ||
2971       (theNod2RValues.Scal >= aTolAng && theNod1RValues.Scal <= -aTolAng))
2972   {
2973     theCoef1 = theNod1RValues.Scal / (theNod2RValues.Scal - theNod1RValues.Scal);
2974     if (theCoef1 < 0) { theCoef1 = -theCoef1; }
2975     theToMoveP1 = theCoef1 < 0.5;
2976     return Standard_True;
2977   }
2978   return Standard_False;
2979 }
2980
2981 //=======================================================================
2982 //function : UVNode
2983 //purpose  :
2984 //=======================================================================
2985 void HLRBRep_PolyAlgo::UVNode (HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
2986                                HLRAlgo_PolyInternalNode::NodeData& theNod2RValues,
2987                                const Standard_Real theCoef1,
2988                                Standard_Real& theU3,
2989                                Standard_Real& theV3) const
2990 {
2991   const Standard_Real aCoef2 = 1.0 - theCoef1;
2992   const gp_XY aUV3 = aCoef2 * theNod1RValues.UV + theCoef1 * theNod2RValues.UV;
2993   theU3 = aUV3.X();
2994   theV3 = aUV3.Y();
2995 }
2996
2997 //=======================================================================
2998 //function : CheckDegeneratedSegment
2999 //purpose  :
3000 //=======================================================================
3001 void HLRBRep_PolyAlgo::CheckDegeneratedSegment (HLRAlgo_PolyInternalNode::NodeIndices& theNod1Indices,
3002                                                 HLRAlgo_PolyInternalNode::NodeData& theNod1RValues,
3003                                                 HLRAlgo_PolyInternalNode::NodeIndices& theNod2Indices,
3004                                                 HLRAlgo_PolyInternalNode::NodeData& theNod2RValues) const
3005 {
3006   theNod1Indices.Flag |=  NMsk_Fuck;
3007   theNod2Indices.Flag |=  NMsk_Fuck;
3008   if ((theNod1RValues.Scal >= myTolAngular && theNod2RValues.Scal <= -myTolAngular) ||
3009       (theNod2RValues.Scal >= myTolAngular && theNod1RValues.Scal <= -myTolAngular))
3010   {
3011     theNod1RValues.Scal  = 0.;
3012     theNod1Indices.Flag |= NMsk_OutL;
3013     theNod2RValues.Scal  = 0.;
3014     theNod2Indices.Flag |= NMsk_OutL;
3015   }
3016 }
3017
3018 //=======================================================================
3019 //function : UpdateOutLines
3020 //purpose  :
3021 //=======================================================================
3022 void HLRBRep_PolyAlgo::UpdateOutLines (HLRAlgo_ListOfBPoint& theList,
3023                                        NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID)
3024 {
3025   Standard_Real X1  ,Y1  ,Z1  ,X2  ,Y2  ,Z2;
3026   Standard_Real XTI1,YTI1,ZTI1,XTI2,YTI2,ZTI2;
3027   const Standard_Integer aNbFaces = myFMap.Extent();
3028   for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
3029   {
3030     const Handle(HLRAlgo_PolyInternalData)& aPid = thePID.ChangeValue (aFaceIter);
3031     if (aPid.IsNull())
3032     {
3033       continue;
3034     }
3035
3036     if (!aPid->IntOutL())
3037     {
3038       continue;
3039     }
3040
3041     HLRAlgo_Array1OfTData& aTData = aPid->TData();
3042     HLRAlgo_Array1OfPISeg& aPISeg = aPid->PISeg();
3043     HLRAlgo_Array1OfPINod& aPINod = aPid->PINod();
3044     Standard_Integer j,it1,it2,tn1,tn2,tn3,pd,pf;
3045     Standard_Boolean isOutl = false;
3046     const Standard_Integer aNbSegs = aPid->NbPISeg();
3047     for (Standard_Integer aSegIter = 1; aSegIter <= aNbSegs; ++aSegIter)
3048     {
3049       const HLRAlgo_PolyInternalSegment& psg = aPISeg.Value (aSegIter);
3050       it1 = psg.Conex1;
3051       it2 = psg.Conex2;
3052       if (it1 != 0 && it2 != 0 && it1 != it2)   // debile but sure !
3053       {
3054         HLRAlgo_TriangleData& aTriangle  = aTData.ChangeValue (it1);
3055         HLRAlgo_TriangleData& aTriangle2 = aTData.ChangeValue (it2);
3056         if      (!(aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) && !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide))
3057         {
3058           isOutl =  (aTriangle.Flags & HLRAlgo_PolyMask_FMskBack) !=  (aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack);
3059         }
3060         else if ( (aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) &&  (aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide))
3061         {
3062           isOutl = Standard_False;
3063         }
3064         else if (  aTriangle.Flags & HLRAlgo_PolyMask_FMskSide)
3065         {
3066           isOutl = !(aTriangle.Flags & HLRAlgo_PolyMask_FMskFlat) && !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack);
3067         }
3068         else
3069         {
3070           isOutl = !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskFlat) && !(aTriangle.Flags & HLRAlgo_PolyMask_FMskBack);
3071         }
3072             
3073         if (isOutl)
3074         {
3075           pd = psg.LstSg1;
3076           pf = psg.LstSg2;
3077           tn1 = aTriangle.Node1;
3078           tn2 = aTriangle.Node2;
3079           tn3 = aTriangle.Node3;
3080           if (!(aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) && (aTriangle.Flags & HLRAlgo_PolyMask_FMskOrBack))
3081           {
3082             j   = tn1;
3083             tn1 = tn3;
3084             tn3 = j;
3085           }
3086           if      ((tn1 == pd && tn2 == pf) || (tn1 == pf && tn2 == pd))
3087           {
3088             aTriangle.Flags |=  HLRAlgo_PolyMask_EMskOutLin1;
3089           }
3090           else if ((tn2 == pd && tn3 == pf) || (tn2 == pf && tn3 == pd))
3091           {
3092             aTriangle.Flags |=  HLRAlgo_PolyMask_EMskOutLin2;
3093           }
3094           else if ((tn3 == pd && tn1 == pf) || (tn3 == pf && tn1 == pd))
3095           {
3096             aTriangle.Flags |=  HLRAlgo_PolyMask_EMskOutLin3;
3097           }
3098         #ifdef OCCT_DEBUG
3099           else if (DoError)
3100           {
3101             std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
3102             std::cout << " : segment not found" << std::endl;
3103           }
3104         #endif
3105           tn1 = aTriangle2.Node1;
3106           tn2 = aTriangle2.Node2;
3107           tn3 = aTriangle2.Node3;
3108           if (!(aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide) && (aTriangle2.Flags & HLRAlgo_PolyMask_FMskOrBack))
3109           {
3110             j   = tn1;
3111             tn1 = tn3;
3112             tn3 = j;
3113           }
3114           if      ((tn1 == pd && tn2 == pf) || (tn1 == pf && tn2 == pd))
3115           {
3116             aTriangle2.Flags |=  HLRAlgo_PolyMask_EMskOutLin1;
3117           }
3118           else if ((tn2 == pd && tn3 == pf) || (tn2 == pf && tn3 == pd))
3119           {
3120             aTriangle2.Flags |=  HLRAlgo_PolyMask_EMskOutLin2;
3121           }
3122           else if ((tn3 == pd && tn1 == pf) || (tn3 == pf && tn1 == pd))
3123           {
3124             aTriangle2.Flags |=  HLRAlgo_PolyMask_EMskOutLin3;
3125           }
3126         #ifdef OCCT_DEBUG
3127           else if (DoError)
3128           {
3129             std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
3130             std::cout << " : segment not found" << std::endl;
3131           }
3132         #endif
3133           const HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = aPINod.Value (pd)->Data();
3134           const HLRAlgo_PolyInternalNode::NodeData& aNod2RValues = aPINod.Value (pf)->Data();
3135           XTI1 = X1 = aNod1RValues.Point.X();
3136           YTI1 = Y1 = aNod1RValues.Point.Y();
3137           ZTI1 = Z1 = aNod1RValues.Point.Z();
3138           XTI2 = X2 = aNod2RValues.Point.X();
3139           YTI2 = Y2 = aNod2RValues.Point.Y();
3140           ZTI2 = Z2 = aNod2RValues.Point.Z();
3141           TIMultiply (XTI1, YTI1, ZTI1);
3142           TIMultiply (XTI2, YTI2, ZTI2);
3143           theList.Append (HLRAlgo_BiPoint (XTI1, YTI1, ZTI1, XTI2, YTI2, ZTI2,
3144                                            X1  , Y1  , Z1  , X2  , Y2  , Z2  ,
3145                                            aFaceIter, aFaceIter, pd, pf, aFaceIter, pd, pf, 12));
3146         }
3147       }
3148     }
3149   }
3150 }
3151
3152 //=======================================================================
3153 //function : UpdateEdgesBiPoints
3154 //purpose  :
3155 //=======================================================================
3156 void HLRBRep_PolyAlgo::UpdateEdgesBiPoints (HLRAlgo_ListOfBPoint& theList,
3157                                             const NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID,
3158                                             const Standard_Boolean theIsClosed)
3159 {
3160   Standard_Integer itri1, itri2, tbid;
3161   for (HLRAlgo_ListIteratorOfListOfBPoint aBPntIter (theList); aBPntIter.More(); aBPntIter.Next())
3162   {
3163     HLRAlgo_BiPoint& aBP = aBPntIter.ChangeValue();
3164     const HLRAlgo_BiPoint::IndicesT& aIndices = aBP.Indices();
3165     if (aIndices.FaceConex1 != 0 && aIndices.FaceConex2 != 0)
3166     {
3167       const Handle(HLRAlgo_PolyInternalData)& aPid1 = thePID.Value (aIndices.FaceConex1);
3168       const Handle(HLRAlgo_PolyInternalData)& aPid2 = thePID.Value (aIndices.FaceConex2);
3169       HLRAlgo_Array1OfPISeg* aPISeg1 = &aPid1->PISeg();
3170       HLRAlgo_Array1OfPISeg* aPISeg2 = &aPid2->PISeg();
3171       HLRAlgo_PolyInternalNode::NodeIndices& aNod11Indices = aPid1->PINod().ChangeValue (aIndices.Face1Pt1)->Indices();
3172       HLRAlgo_PolyInternalNode::NodeIndices& aNod21Indices = aPid2->PINod().ChangeValue (aIndices.Face2Pt1)->Indices();
3173       Triangles (aIndices.Face1Pt1, aIndices.Face1Pt2, aNod11Indices, aPISeg1, itri1, tbid);
3174       Triangles (aIndices.Face2Pt1, aIndices.Face2Pt2, aNod21Indices, aPISeg2, itri2, tbid);
3175
3176       if (itri1 != 0 && itri2 != 0)
3177       {
3178         if (aIndices.FaceConex1 != aIndices.FaceConex2 || itri1 != itri2)
3179         {
3180           HLRAlgo_Array1OfTData* aTData1 = &aPid1->TData();
3181           HLRAlgo_Array1OfTData* aTData2 = &aPid2->TData();
3182           HLRAlgo_TriangleData& aTriangle  = aTData1->ChangeValue (itri1);
3183           HLRAlgo_TriangleData& aTriangle2 = aTData2->ChangeValue (itri2);
3184           if (theIsClosed)
3185           {
3186             if (((aTriangle.Flags & HLRAlgo_PolyMask_FMskBack) && (aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack)) ||
3187                 ((aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) && (aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide)) ||
3188                 ((aTriangle.Flags & HLRAlgo_PolyMask_FMskBack) && (aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide)) ||
3189                 ((aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) && (aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack)))
3190             {
3191               aBP.Hidden (Standard_True);
3192             }
3193           }
3194
3195           Standard_Boolean isOutl;
3196           if      (!(aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) && !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide))
3197           {
3198             isOutl =  (aTriangle.Flags & HLRAlgo_PolyMask_FMskBack) !=  (aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack);
3199           }
3200           else if ( (aTriangle.Flags & HLRAlgo_PolyMask_FMskSide) &&  (aTriangle2.Flags & HLRAlgo_PolyMask_FMskSide))
3201           {
3202             isOutl = Standard_False;
3203           }
3204           else if ( (aTriangle.Flags & HLRAlgo_PolyMask_FMskSide))
3205           {
3206             isOutl = !(aTriangle.Flags & HLRAlgo_PolyMask_FMskFlat) && !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskBack);
3207           }
3208           else
3209           {
3210             isOutl = !(aTriangle2.Flags & HLRAlgo_PolyMask_FMskFlat) && !(aTriangle.Flags & HLRAlgo_PolyMask_FMskBack);
3211           }
3212           aBP.OutLine (isOutl);
3213         }
3214       }
3215 #ifdef OCCT_DEBUG
3216       else if (DoError)
3217       {
3218         std::cout << "HLRBRep_PolyAlgo::UpdateEdgesBiPoints : error ";
3219         std::cout << " between " << aIndices.FaceConex1 << std::setw(6);
3220         std::cout << " and " << aIndices.FaceConex2 << std::endl;
3221       }
3222 #endif
3223     }
3224   }
3225 }
3226
3227 //=======================================================================
3228 //function : UpdatePolyData
3229 //purpose  :
3230 //=======================================================================
3231 void HLRBRep_PolyAlgo::UpdatePolyData (NCollection_Array1<Handle(HLRAlgo_PolyData)>& thePD,
3232                                        NCollection_Array1<Handle(HLRAlgo_PolyInternalData)>& thePID,
3233                                        const Standard_Boolean theIsClosed)
3234 {
3235   const Standard_Integer aNbFaces = myFMap.Extent();
3236   for (Standard_Integer aFaceIter = 1; aFaceIter <= aNbFaces; ++aFaceIter)
3237   {
3238     const Handle(HLRAlgo_PolyInternalData)& aPid = thePID.ChangeValue (aFaceIter);
3239     if (aPid.IsNull())
3240     {
3241       continue;
3242     }
3243
3244     const Standard_Integer aNbNodes = aPid->NbPINod();
3245     const Standard_Integer aNbTris  = aPid->NbTData();
3246     Handle(TColgp_HArray1OfXYZ)    aHNodes = new TColgp_HArray1OfXYZ   (1, aNbNodes);
3247     Handle(HLRAlgo_HArray1OfTData) aHTData = new HLRAlgo_HArray1OfTData(1, aNbTris);
3248     TColgp_Array1OfXYZ&    aNodes = aHNodes->ChangeArray1();
3249     HLRAlgo_Array1OfTData& aTrian = aHTData->ChangeArray1();
3250     HLRAlgo_Array1OfTData& aTData = aPid->TData();
3251     HLRAlgo_Array1OfPINod& aPINod = aPid->PINod();
3252     Standard_Integer aNbHidden = 0;
3253
3254     for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
3255     {
3256       const HLRAlgo_PolyInternalNode::NodeData& aNod1RValues = aPINod.Value (aNodeIter)->Data();
3257       aNodes.SetValue (aNodeIter, aNod1RValues.Point);
3258     }
3259
3260     for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
3261     {
3262       HLRAlgo_TriangleData& anOT = aTData.ChangeValue (aTriIter);
3263       HLRAlgo_TriangleData& aNT  = aTrian.ChangeValue (aTriIter);
3264       if (!(anOT.Flags & HLRAlgo_PolyMask_FMskSide))
3265       {
3266       #ifdef OCCT_DEBUG
3267         if ((anOT.Flags & HLRAlgo_PolyMask_FMskFrBack) && DoTrace)
3268         {
3269           std::cout << "HLRBRep_PolyAlgo::ReverseBackTriangle :";
3270           std::cout << " face " << aFaceIter << std::setw(6);
3271           std::cout << " triangle " << aTriIter << std::endl;
3272         }
3273       #endif
3274         if (anOT.Flags & HLRAlgo_PolyMask_FMskOrBack)
3275         {
3276           Standard_Integer j = anOT.Node1;
3277           anOT.Node1 = anOT.Node3;
3278           anOT.Node3 = j;
3279           anOT.Flags |= HLRAlgo_PolyMask_FMskBack;
3280         }
3281         else
3282         {
3283           anOT.Flags &= ~HLRAlgo_PolyMask_FMskBack;
3284           //Tri1Flags |= HLRAlgo_PolyMask_FMskBack;//OCC349
3285         }
3286       }
3287       aNT.Node1 = anOT.Node1;
3288       aNT.Node2 = anOT.Node2;
3289       aNT.Node3 = anOT.Node3;
3290       aNT.Flags = anOT.Flags;
3291       if (!(aNT.Flags & HLRAlgo_PolyMask_FMskSide) &&
3292           (!(aNT.Flags & HLRAlgo_PolyMask_FMskBack) || !theIsClosed))
3293       {
3294         aNT.Flags |=  HLRAlgo_PolyMask_FMskHiding;
3295         ++aNbHidden;
3296       }
3297       else
3298       {
3299         aNT.Flags &= ~HLRAlgo_PolyMask_FMskHiding;
3300       }
3301     }
3302
3303     Handle(HLRAlgo_HArray1OfPHDat) aHPHDat;
3304     if (aNbHidden > 0)
3305     {
3306       aHPHDat = new HLRAlgo_HArray1OfPHDat (1, aNbHidden);
3307     }
3308
3309     const Handle(HLRAlgo_PolyData)& aPd = thePD.ChangeValue (aFaceIter);
3310     aPd->HNodes (aHNodes);
3311     aPd->HTData (aHTData);
3312     aPd->HPHDat (aHPHDat);
3313     aPd->FaceIndex (aFaceIter);
3314   }
3315 }
3316
3317 //=======================================================================
3318 //function : TMultiply
3319 //purpose  :
3320 //=======================================================================
3321 void HLRBRep_PolyAlgo::TMultiply (Standard_Real& theX,
3322                                   Standard_Real& theY,
3323                                   Standard_Real& theZ,
3324                                   const Standard_Boolean theVPO) const
3325 {
3326   Standard_Real Xt = TMat[0][0] * theX + TMat[0][1] * theY + TMat[0][2] * theZ + (theVPO ? 0 : TLoc[0]);//OCC349
3327   Standard_Real Yt = TMat[1][0] * theX + TMat[1][1] * theY + TMat[1][2] * theZ + (theVPO ? 0 : TLoc[1]);//OCC349
3328   theZ             = TMat[2][0] * theX + TMat[2][1] * theY + TMat[2][2] * theZ + (theVPO ? 0 : TLoc[2]);//OCC349
3329   theX             = Xt;
3330   theY             = Yt;
3331 }
3332
3333 //=======================================================================
3334 //function : TTMultiply
3335 //purpose  :
3336 //=======================================================================
3337 void HLRBRep_PolyAlgo::TTMultiply (Standard_Real& theX,
3338                                    Standard_Real& theY,
3339                                    Standard_Real& theZ,
3340                                    const Standard_Boolean theVPO) const
3341 {
3342   Standard_Real Xt = TTMa[0][0] * theX + TTMa[0][1] * theY + TTMa[0][2] * theZ + (theVPO ? 0 : TTLo[0]);//OCC349
3343   Standard_Real Yt = TTMa[1][0] * theX + TTMa[1][1] * theY + TTMa[1][2] * theZ + (theVPO ? 0 : TTLo[1]);//OCC349
3344   theZ             = TTMa[2][0] * theX + TTMa[2][1] * theY + TTMa[2][2] * theZ + (theVPO ? 0 : TTLo[2]);//OCC349
3345   theX             = Xt;
3346   theY             = Yt;
3347 }
3348
3349 //=======================================================================
3350 //function : TIMultiply
3351 //purpose  :
3352 //=======================================================================
3353 void HLRBRep_PolyAlgo::TIMultiply (Standard_Real& theX,
3354                                    Standard_Real& theY,
3355                                    Standard_Real& theZ,
3356                                    const Standard_Boolean theVPO) const
3357 {
3358   Standard_Real Xt = TIMa[0][0] * theX + TIMa[0][1] * theY + TIMa[0][2] * theZ + (theVPO ? 0 : TILo[0]);//OCC349
3359   Standard_Real Yt = TIMa[1][0] * theX + TIMa[1][1] * theY + TIMa[1][2] * theZ + (theVPO ? 0 : TILo[1]);//OCC349
3360   theZ             = TIMa[2][0] * theX + TIMa[2][1] * theY + TIMa[2][2] * theZ + (theVPO ? 0 : TILo[2]);//OCC349
3361   theX             = Xt;
3362   theY             = Yt;
3363 }
3364
3365 //=======================================================================
3366 //function : Hide
3367 //purpose  :
3368 //=======================================================================
3369 HLRAlgo_BiPoint::PointsT& HLRBRep_PolyAlgo::Hide (HLRAlgo_EdgeStatus& theStatus,
3370                                                   TopoDS_Shape& theShape,
3371                                                   Standard_Boolean& theReg1,
3372                                                   Standard_Boolean& theRegn,
3373                                                   Standard_Boolean& theOutl,
3374                                                   Standard_Boolean& theIntl)
3375 {
3376   Standard_Integer anIndex = 0;
3377   HLRAlgo_BiPoint::PointsT& aPoints = myAlgo->Hide (theStatus, anIndex, theReg1, theRegn, theOutl, theIntl);
3378   theShape = theIntl
3379            ? myFMap (anIndex)
3380            : myEMap (anIndex);
3381   return aPoints;
3382 }
3383
3384 //=======================================================================
3385 //function : Show
3386 //purpose  :
3387 //=======================================================================
3388 HLRAlgo_BiPoint::PointsT& HLRBRep_PolyAlgo::Show (TopoDS_Shape& theShape,
3389                                                   Standard_Boolean& theReg1,
3390                                                   Standard_Boolean& theRegn,
3391                                                   Standard_Boolean& theOutl,
3392                                                   Standard_Boolean& theIntl)
3393 {
3394   Standard_Integer anIndex = 0;
3395   HLRAlgo_BiPoint::PointsT& aPoints = myAlgo->Show (anIndex, theReg1, theRegn, theOutl, theIntl);
3396   theShape = theIntl
3397            ? myFMap (anIndex)
3398            : myEMap (anIndex);
3399   return aPoints;
3400 }
3401
3402 //=======================================================================
3403 //function : OutLinedShape
3404 //purpose  :
3405 //=======================================================================
3406 TopoDS_Shape HLRBRep_PolyAlgo::OutLinedShape (const TopoDS_Shape& theShape) const
3407 {
3408   if (theShape.IsNull())
3409   {
3410     return TopoDS_Shape();
3411   }
3412
3413   TopoDS_Shape aResult;
3414   BRep_Builder aBuilder;
3415   aBuilder.MakeCompound (TopoDS::Compound (aResult));
3416   aBuilder.Add (aResult, theShape);
3417   if (myFMap.IsEmpty())
3418   {
3419     return aResult;
3420   }
3421
3422   TopTools_MapOfShape aMap;
3423   {
3424     TopExp_Explorer aShapeExp;
3425     for (aShapeExp.Init (theShape, TopAbs_EDGE); aShapeExp.More(); aShapeExp.Next())
3426     {
3427       aMap.Add (aShapeExp.Current());
3428     }
3429     for (aShapeExp.Init (theShape, TopAbs_FACE); aShapeExp.More(); aShapeExp.Next())
3430     {
3431       aMap.Add (aShapeExp.Current());
3432     }
3433   }
3434
3435   const NCollection_Array1<Handle(HLRAlgo_PolyShellData)>& aShell = myAlgo->PolyShell();
3436   const Standard_Integer aNbShells = aShell.Upper();
3437   HLRAlgo_ListIteratorOfListOfBPoint aBPntIter;
3438   for (Standard_Integer aShellIter = 1; aShellIter <= aNbShells; ++aShellIter)
3439   {
3440     const HLRAlgo_ListOfBPoint& aList = aShell.Value (aShellIter)->Edges();
3441     for (aBPntIter.Initialize (aList); aBPntIter.More(); aBPntIter.Next())
3442     {
3443       HLRAlgo_BiPoint& aBP = aBPntIter.ChangeValue();
3444       if (aBP.IntLine())
3445       {
3446         const HLRAlgo_BiPoint::IndicesT& aIndices = aBP.Indices();
3447         if (aMap.Contains (myFMap (aIndices.ShapeIndex)))
3448         {
3449           const HLRAlgo_BiPoint::PointsT& aPoints = aBP.Points();
3450           aBuilder.Add (aResult, BRepLib_MakeEdge (aPoints.Pnt1, aPoints.Pnt2));
3451         }
3452       }
3453     }
3454   }
3455
3456   return aResult;
3457 }