Commit | Line | Data |
---|---|---|
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 | // |
973c2be1 | 7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public 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. | |
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 | ||
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 | ||
126b0763 RL |
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 | ||
7fd59977 | 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 | ||
eafb234b | 202 | if (GTranslate3d && GTranslate2d) { |
7fd59977 | 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; | |
eafb234b | 209 | } |
7fd59977 | 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) { | |
126b0763 RL |
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); | |
7fd59977 | 407 | } |
408 | else { | |
409 | mysewd = Gsewd; | |
410 | mysewd3d = Gsewd3d; | |
411 | mysewd2d = Gsewd2d; | |
412 | } | |
413 | return okCurve; | |
414 | } | |
415 |