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