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