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