]>
Commit | Line | Data |
---|---|---|
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 | ||
65 | IGESControl_IGESBoundary::IGESControl_IGESBoundary() : IGESToBRep_IGESBoundary() | |
66 | { | |
67 | } | |
68 | ||
69 | //======================================================================= | |
70 | //function : IGESControl_IGESBoundary | |
71 | //purpose : | |
72 | //======================================================================= | |
73 | ||
74 | IGESControl_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 | ||
126b0763 RL |
122 | //======================================================================= |
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 | //======================================================================= | |
133 | static 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 | ||
7fd59977 | 153 | //======================================================================= |
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 |