0031939: Coding - correction of spelling errors in comments [part 4]
[occt.git] / src / IGESControl / IGESControl_IGESBoundary.cxx
1 // Created on: 2000-02-05
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <Geom2d_Curve.hxx>
20 #include <Geom_Curve.hxx>
21 #include <Geom_Plane.hxx>
22 #include <GeomAdaptor_Curve.hxx>
23 #include <IGESControl_IGESBoundary.hxx>
24 #include <IGESData_IGESEntity.hxx>
25 #include <IGESGeom_BSplineCurve.hxx>
26 #include <IGESToBRep.hxx>
27 #include <IGESToBRep_CurveAndSurface.hxx>
28 #include <IGESToBRep_TopoCurve.hxx>
29 #include <Interface_Static.hxx>
30 #include <Message_Msg.hxx>
31 #include <Precision.hxx>
32 #include <ShapeAlgo.hxx>
33 #include <ShapeAlgo_AlgoContainer.hxx>
34 #include <ShapeAlgo_ToolContainer.hxx>
35 #include <ShapeAnalysis_ShapeTolerance.hxx>
36 #include <ShapeAnalysis_Wire.hxx>
37 #include <ShapeBuild_Edge.hxx>
38 #include <ShapeExtend_WireData.hxx>
39 #include <ShapeFix_Edge.hxx>
40 #include <ShapeFix_ShapeTolerance.hxx>
41 #include <ShapeFix_Wire.hxx>
42 #include <Standard_Type.hxx>
43 #include <TColStd_HSequenceOfTransient.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Wire.hxx>
46
47 IMPLEMENT_STANDARD_RTTIEXT(IGESControl_IGESBoundary,IGESToBRep_IGESBoundary)
48
49 //=======================================================================
50 //function : IGESControl_IGESBoundary
51 //purpose  : 
52 //=======================================================================
53 IGESControl_IGESBoundary::IGESControl_IGESBoundary() : IGESToBRep_IGESBoundary()
54 {
55 }
56
57 //=======================================================================
58 //function : IGESControl_IGESBoundary
59 //purpose  : 
60 //=======================================================================
61
62 IGESControl_IGESBoundary::IGESControl_IGESBoundary(const IGESToBRep_CurveAndSurface& CS) :
63        IGESToBRep_IGESBoundary (CS)
64 {
65 }
66
67 //=======================================================================
68 //function : Check
69 //purpose  : 
70 //=======================================================================
71
72  void IGESControl_IGESBoundary::Check(const Standard_Boolean result,const Standard_Boolean checkclosure,
73                                       const Standard_Boolean aokCurve3d, const Standard_Boolean aokCurve2d) 
74 {
75   Standard_Boolean Result = result;
76   Standard_Boolean okCurve3d = aokCurve3d, okCurve2d = aokCurve2d; 
77   Standard_Real maxtol = myCS.GetMaxTol();
78   
79   if (Result && checkclosure) {
80     //USA60022 7277 check of closure
81     Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
82     saw->Load (mysewd);
83     saw->SetPrecision (maxtol);
84     saw->CheckConnected (1);
85     if (saw->LastCheckStatus (ShapeExtend_FAIL)) {
86       saw->Load (mysewd3d);
87       saw->CheckConnected (1);
88       if (saw->LastCheckStatus (ShapeExtend_FAIL)) okCurve3d = Standard_False;
89       else                                         okCurve2d = Standard_False;
90       Result = Standard_False;
91     }
92   }
93   if (!Result) {
94     mysewd->Clear();
95     if (okCurve3d && mysewd3d->NbEdges() > 0) {
96       Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 3d"
97       Msg1070.Arg(3);
98       myCS.SendWarning(myentity,Msg1070);
99       mysewd = mysewd3d;
100     }
101     else if (okCurve2d && mysewd2d->NbEdges() > 0) {
102       Message_Msg Msg1070("IGES_1070");//"Representations in the file are inconsistent. Recomputation from 2d"
103       Msg1070.Arg(2);
104       myCS.SendWarning(myentity,Msg1070);
105       mysewd = mysewd2d;
106     }
107   }
108 }
109
110 //=======================================================================
111 //function : Connect
112 //purpose  : Connects theNextWD to theWD using theSAW. 
113 //           First, connects edges of theNextWD by calling ShapeFix_Wire::FixConnected(). This
114 //           is necessary when theNextWD was built using multiple curves from the Composite
115 //           Curve (as ShapeExtend_WireData::Wire() would otherwise produce a wrong 
116 //           disconnected TopoDS_Wire).
117 //           FixConnected() will only update the edges resulting from different composite
118 //           curve segments. Edges resulting from splitting C0 curve will already be
119 //           connected.
120 //=======================================================================
121 static Standard_Boolean Connect (const Handle(ShapeAnalysis_Wire)& theSAW,
122                                  const Handle(ShapeExtend_WireData)& theWD,
123                                  const Handle(ShapeExtend_WireData)& theNextWD,
124                                  const Standard_Boolean theConnectNextWD,
125                                  const Standard_Real theMaxTol,
126                                  Standard_Real& theDistMin,
127                                  Standard_Boolean& theReverseWD,
128                                  Standard_Boolean& theReverseNextWD)
129 {
130     theSAW->Load (theWD);
131     if (theConnectNextWD) {
132       Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
133       sfw->Load (theNextWD);
134       sfw->ClosedWireMode() = Standard_False; //internal connections are enough
135       sfw->FixConnected();
136     }
137     return ShapeAlgo::AlgoContainer()->ConnectNextWire (theSAW, theNextWD,
138       theMaxTol, theDistMin, theReverseWD, theReverseNextWD);
139 }
140
141 //=======================================================================
142 //function : Transfer
143 //purpose  : 
144 //=======================================================================
145
146  Standard_Boolean IGESControl_IGESBoundary::Transfer(Standard_Boolean& okCurve,
147                                                      Standard_Boolean& okCurve3d,
148                                                      Standard_Boolean& okCurve2d,
149                                                      const Handle(IGESData_IGESEntity)& icurve3d,
150                                                      const Handle(ShapeExtend_WireData)& scurve3d,
151                                                      const Standard_Boolean usescurve,
152                                                      const Standard_Boolean toreverse3d,
153                                                      const Handle(IGESData_HArray1OfIGESEntity)& curves2d,
154                                                      const Standard_Boolean toreverse2d,
155                                                      const Standard_Integer number,
156                                                      Handle(ShapeExtend_WireData)& Gsewd) 
157 {
158   Gsewd                                = new ShapeExtend_WireData;//local translation (for mysewd)
159   Handle(ShapeExtend_WireData) Gsewd3d = new ShapeExtend_WireData;//local translation (for mysewd3d)
160   Handle(ShapeExtend_WireData) Gsewd2d = new ShapeExtend_WireData;//local translation (for mysewd2d)
161
162   Standard_Boolean revsewd, revnextsewd;
163   Standard_Real distmin, precision = myCS.GetEpsGeom() * myCS.GetUnitFactor(), maxtol = myCS.GetMaxTol();
164   
165   Handle(ShapeAnalysis_Wire) saw   = new ShapeAnalysis_Wire,
166                              saw3d = new ShapeAnalysis_Wire,
167                              saw2d = new ShapeAnalysis_Wire;
168   saw->Load   (Gsewd);   saw->SetPrecision   (precision);
169   saw3d->Load (Gsewd3d); saw3d->SetPrecision (precision);
170   saw2d->Load (Gsewd2d); saw2d->SetPrecision (precision);
171   
172   Standard_Boolean GTranslate3d = Standard_True, GTranslate2d = Standard_True,
173                    Preferred3d  = Standard_True, Preferred2d  = Standard_True;
174
175   Standard_Integer len3d = 0, len2d = 0;
176   Handle(TColStd_HSequenceOfTransient) seq3d, seq2d;
177   if (usescurve)
178     len3d = scurve3d->NbEdges();
179   else {
180     IGESToBRep::IGESCurveToSequenceOfIGESCurve (icurve3d, seq3d);
181       len3d = seq3d->Length();
182   }
183   if (!curves2d.IsNull()) {
184     for (Standard_Integer i = 1; i <= curves2d->Length(); i++)
185       IGESToBRep::IGESCurveToSequenceOfIGESCurve (curves2d->Value (i), seq2d);
186     len2d = seq2d->Length();
187   }
188
189   Standard_Integer surfcurv = myCS.GetSurfaceCurve();
190   if ((surfcurv == -2 && len2d > 0) || len3d == 0)
191     GTranslate3d = Standard_False;
192   else if (( surfcurv == -3 && len3d > 0) || len2d == 0)
193     GTranslate2d = Standard_False;
194  
195   if (GTranslate3d && GTranslate2d) {
196     //Setting preference in the case of inconsitency between 3D and 2D
197     if      (surfcurv == 2)         Preferred3d = Standard_False;
198     else if (surfcurv == 3)         Preferred2d = Standard_False;
199     else if (myfilepreference == 2) Preferred3d = Standard_False;
200     else if (myfilepreference == 3) Preferred2d = Standard_False;
201     else                            Preferred3d = Standard_False;
202   }
203   if (GTranslate3d && GTranslate2d && len3d != len2d) {
204     GTranslate3d = Preferred3d;
205     GTranslate2d = Preferred2d;
206   }
207     
208   IGESToBRep_TopoCurve TC (myCS);
209   
210   if (GTranslate3d && !GTranslate2d) {
211     if (usescurve) {
212       Gsewd->Add(scurve3d->Wire());
213     }
214     else {
215       TopoDS_Shape Sh = TC.TransferTopoCurve (icurve3d);
216       if (!Sh.IsNull()) {
217         Gsewd3d->Add (Sh);
218         if (toreverse3d) {
219           ReverseCurves3d (Gsewd3d);
220           Gsewd->Add (Gsewd3d->Wire());
221         }
222         else Gsewd->Add (Sh);//Gsewd = Gsewd3d is impossible to avoid sharing of sewd (UK1.igs entity 7)
223       }
224     }
225   }
226   else if (!GTranslate3d && GTranslate2d) {
227     for (Standard_Integer i = curves2d->Lower(); i <= curves2d->Upper(); i++) {
228       TopoDS_Shape Sh = TC.Transfer2dTopoCurve (curves2d->Value (i), myface, mytrsf, myuFact);
229       if (!Sh.IsNull()) Gsewd2d->Add (Sh);
230     }
231     if (toreverse2d) {
232       ReverseCurves2d (Gsewd2d, myface);
233     }
234     Gsewd->Add (Gsewd2d->Wire());
235   }
236   else if( GTranslate3d && GTranslate2d ) {
237     //Translate both curves 3D and 2D
238     //Suppose that i-th segment in 2D curve corresponds to i-th segment in 3D curve
239     for (Standard_Integer i = 1; i <= len3d; i++) {
240       Standard_Boolean LTranslate3d = Standard_True, LTranslate2d = Standard_True;
241       
242       Handle(ShapeExtend_WireData) Lsewd3d = new ShapeExtend_WireData;
243       TC.SetBadCase (Standard_False); //:27
244       if (usescurve)
245         Lsewd3d->Add (scurve3d->Edge (i));
246       else {
247         TopoDS_Shape shape3d = TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (i)));
248         if (!shape3d.IsNull()) {
249           Lsewd3d->Add (shape3d);
250           if (toreverse3d) {
251             ReverseCurves3d (Lsewd3d);
252           }
253         }
254         else LTranslate3d = Standard_False;
255       }
256       Standard_Boolean bad3d = TC.BadCase(); //:27
257       okCurve3d = okCurve3d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw3d, Lsewd3d, maxtol, distmin, revsewd, revnextsewd);
258       
259       Handle(ShapeExtend_WireData) Lsewd2d = new ShapeExtend_WireData;
260       TC.SetBadCase (Standard_False); //:27
261       TopoDS_Shape shape2d = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (i)),
262                                                      myface, mytrsf, myuFact);
263       Standard_Boolean bad2d = TC.BadCase(); //:27
264       if (!shape2d.IsNull()) {
265         Lsewd2d->Add  (shape2d);
266         if (toreverse2d) {
267           ReverseCurves2d (Lsewd2d, myface);
268         }
269         okCurve2d = okCurve2d && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw2d, Lsewd2d, maxtol, distmin, revsewd, revnextsewd);
270       }
271       else LTranslate2d = Standard_False;
272       
273 //     if (LTranslate3d && LTranslate2d && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges() || bad3d || bad2d)) {
274       Standard_Boolean isBSpline = Standard_False;
275       if(!usescurve && !seq3d->Value (i).IsNull() && !seq2d->Value (i).IsNull())
276         isBSpline = seq3d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve)) &&
277           seq2d->Value (i)->IsKind(STANDARD_TYPE(IGESGeom_BSplineCurve));
278       
279       if (LTranslate3d && LTranslate2d && 
280           (
281            (isBSpline && (Lsewd3d->NbEdges() != Lsewd2d->NbEdges())) ||
282            (!isBSpline && (Lsewd3d->NbEdges() != 1 || Lsewd2d->NbEdges() != 1)) ||
283            bad3d || bad2d
284            )) {
285         
286         LTranslate3d = Preferred3d;
287         LTranslate2d = Preferred2d;
288       }
289       Handle(ShapeExtend_WireData) Lsewd;//Lsewd3d or Lsewd2d or Lsewd3d+pcurve
290       if      ( LTranslate3d && !LTranslate2d) Lsewd = Lsewd3d;
291       else if (!LTranslate3d &&  LTranslate2d) Lsewd = Lsewd2d;
292       else {
293         Lsewd = Lsewd3d;
294         //copying pcurve to edge with 3D curve
295         Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
296         for (Standard_Integer iedge = 1; iedge <= Lsewd3d->NbEdges(); iedge++) {
297           TopoDS_Edge edge3d = Lsewd3d->Edge (iedge), edge2d = Lsewd2d->Edge (iedge);
298           if (!IGESToBRep::TransferPCurve (edge2d, edge3d, myface)) continue;
299           if (sfe->FixReversed2d (edge3d, myface)) {
300 #ifdef OCCT_DEBUG
301             std::cout << "Warning: IGESToBRep_IGESBoundary: 2D curve of edge was reversed" << std::endl;
302 #endif
303           }
304           //#74 rln 10.03.99 S4135: handling use of BRepLib::SameParameter by new static parameter
305           if (Interface_Static::IVal ("read.stdsameparameter.mode")) {
306             Standard_Real first, last;
307             BRep_Tool::Range(edge3d,first,last);
308             // pdn 08.04.99 S4135 optimizing in computation of SPTol
309             //choosing tolerance according to Approx_SameParameter: 50 * 22
310             Standard_Real SPTol = Min (precision, Abs (last - first)/1000);
311             BRep_Builder B;
312             B.SameParameter (edge3d, Standard_False);
313             sfe->FixSameParameter (edge3d, SPTol);
314           }
315           else
316             sfe->FixSameParameter (edge3d);
317           Standard_Real maxdev = BRep_Tool::Tolerance (edge3d);
318           //pdn 08.04.99 S4135 recomputing only if deviation is greater than maxtol
319           if (maxdev > maxtol) { //:e2
320 #ifdef OCCT_DEBUG
321             std::cout << "Warning: IGESToBRep_IGESBoundary: Deviation = " << maxdev << std::endl;
322 #endif
323             ShapeFix_ShapeTolerance().SetTolerance (edge3d, Precision::Confusion());
324             for (Standard_Integer ie = 1; ie <= iedge; ie++)
325               ShapeBuild_Edge().RemovePCurve (Lsewd3d->Edge (ie), myface);
326             if (Preferred3d) {
327 #ifdef OCCT_DEBUG
328               std::cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 2D is ignored" << std::endl;
329 #endif
330             }
331             else {
332 #ifdef OCCT_DEBUG
333               std::cout << "Warning: IGESToBRep_IGESBoundary: 3D and 2D curves are inconsistent; 3D is ignored" << std::endl;
334 #endif
335               Lsewd = Lsewd2d;
336             }
337             break;
338           }
339         }
340       }
341       okCurve = okCurve && ShapeAlgo::AlgoContainer()->ConnectNextWire (saw, Lsewd, maxtol, distmin, revsewd, revnextsewd);
342       if (!okCurve) {
343 #ifdef OCCT_DEBUG
344         std::cout << "Warning: IGESToBRep_IGESBoundary: Curves " << i - 1 << " and " << i << " cannot be connected" << std::endl;
345 #endif
346         Gsewd3d = new ShapeExtend_WireData;
347         for (Standard_Integer j = 1; j <= len3d; j++) {
348           if (usescurve)
349             Gsewd3d->Add (scurve3d->Edge (j));
350           else {
351             TopoDS_Shape Sh =
352               TC.TransferTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq3d->Value (j)));
353             if (!Sh.IsNull()) Gsewd3d->Add (Sh);
354           }
355         }
356         if (toreverse3d) {
357           ReverseCurves3d(Gsewd3d);
358         }
359         Gsewd2d = new ShapeExtend_WireData;
360         for (Standard_Integer k = 1; k <= len2d; k++) {
361           TopoDS_Shape Sh = TC.Transfer2dTopoCurve (Handle(IGESData_IGESEntity)::DownCast (seq2d->Value (k)),
362                                                     myface, mytrsf, myuFact);
363           if (!Sh.IsNull()) Gsewd2d->Add (Sh);
364         }
365         if (toreverse2d) {
366           ReverseCurves2d (Gsewd2d, myface);
367         }
368         Handle(ShapeFix_Wire) sfw3 = new ShapeFix_Wire(Gsewd3d->Wire(),myface,precision);
369         sfw3->Perform();
370         TopoDS_Wire w3 = sfw3->Wire();
371         Handle(ShapeFix_Wire) sfw2 = new ShapeFix_Wire(Gsewd2d->Wire(),myface,precision);
372         sfw2->Perform();
373         TopoDS_Wire w2 = sfw2->Wire();
374         ShapeAnalysis_ShapeTolerance ST;
375         double tol3 = ST.Tolerance(w3,1);
376         double tol2 = ST.Tolerance(w2,1);
377         Gsewd3d = new ShapeExtend_WireData;
378         Gsewd2d = new ShapeExtend_WireData;
379         Gsewd3d->Add(w3);
380         Gsewd2d->Add(w3);
381         if(tol3<tol2)
382           Gsewd->Add(w3);
383         else
384           Gsewd->Add(w2);
385         okCurve = Standard_True;
386         okCurve2d = Standard_True;
387         okCurve3d = Standard_True;
388       }
389     }
390   }
391   
392   if (number > 1) {
393     okCurve   = okCurve && Connect (saw, mysewd, Gsewd, (len3d > 1) || (len2d > 1), maxtol,
394       distmin, revsewd, revnextsewd);
395     okCurve3d = okCurve3d && Connect (saw3d, mysewd3d, Gsewd3d, len3d > 1, maxtol,
396       distmin, revsewd, revnextsewd);
397     okCurve2d = okCurve2d && Connect (saw2d, mysewd2d, Gsewd2d, len2d > 1, maxtol,
398       distmin, revsewd, revnextsewd);
399   }
400   else {
401     mysewd   = Gsewd;
402     mysewd3d = Gsewd3d;
403     mysewd2d = Gsewd2d;
404   }
405   return okCurve;
406 }
407