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