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