b311480e |
1 | // Created on: 1999-08-24 |
2 | // Created by: Sergei ZERTCHANINOV |
3 | // Copyright (c) 1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | #include <ShapeFix_Wireframe.ixx> |
23 | |
24 | #include <Standard_Failure.hxx> |
25 | #include <Standard_ErrorHandler.hxx> |
26 | |
27 | //#include <Geom2dConvert_CompCurveToBSplineCurve.hxx> |
28 | #include <ShapeBuild_ReShape.hxx> |
29 | #include <TopTools_DataMapOfShapeShape.hxx> |
30 | #include <TopoDS_Compound.hxx> |
31 | #include <BRep_Builder.hxx> |
32 | #include <TopoDS_Iterator.hxx> |
33 | #include <ShapeFix_Wire.hxx> |
34 | #include <TopoDS_Face.hxx> |
35 | #include <TopExp_Explorer.hxx> |
36 | #include <TopoDS.hxx> |
37 | #include <ShapeFix.hxx> |
38 | #include <ShapeFix_Edge.hxx> |
39 | #include <ShapeConstruct_Curve.hxx> |
40 | #include <TopoDS_Edge.hxx> |
41 | #include <TopoDS_Vertex.hxx> |
42 | #include <ShapeAnalysis_Edge.hxx> |
43 | #include <Geom_Curve.hxx> |
44 | #include <Geom_BSplineCurve.hxx> |
45 | #include <gp_Pnt.hxx> |
46 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
47 | #include <BRep_Tool.hxx> |
48 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
49 | #include <Geom2d_Curve.hxx> |
50 | #include <Geom2d_BSplineCurve.hxx> |
51 | #include <gp_Pln.hxx> |
52 | #include <GeomAPI.hxx> |
53 | #include <TopTools_ListOfShape.hxx> |
54 | #include <TopTools_MapOfShape.hxx> |
55 | #include <TopTools_DataMapOfShapeListOfShape.hxx> |
56 | #include <TopTools_DataMapOfShapeInteger.hxx> |
57 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
58 | #include <ShapeConstruct.hxx> |
59 | #include <ShapeBuild_Edge.hxx> |
60 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
61 | |
62 | //======================================================================= |
63 | //function : ShapeFix_Wireframe |
64 | //purpose : |
65 | //======================================================================= |
66 | |
67 | ShapeFix_Wireframe::ShapeFix_Wireframe() |
68 | { |
69 | ClearStatuses(); |
70 | myModeDrop = Standard_False; |
71 | myLimitAngle = -1; |
72 | } |
73 | |
74 | //======================================================================= |
75 | //function : ShapeFix_Wireframe |
76 | //purpose : |
77 | //======================================================================= |
78 | |
79 | ShapeFix_Wireframe::ShapeFix_Wireframe(const TopoDS_Shape& shape) |
80 | { |
81 | ClearStatuses(); |
82 | myShape = shape; |
83 | myModeDrop = Standard_False; |
84 | myLimitAngle = -1; |
85 | } |
86 | |
87 | //======================================================================= |
88 | //function : ClearStatuses |
89 | //purpose : |
90 | //======================================================================= |
91 | |
92 | void ShapeFix_Wireframe::ClearStatuses() |
93 | { |
94 | Standard_Integer emptyStatus = ShapeExtend::EncodeStatus( ShapeExtend_OK ); |
95 | |
96 | myStatusWireGaps = emptyStatus; |
97 | myStatusSmallEdges = emptyStatus; |
98 | } |
99 | |
100 | //======================================================================= |
101 | //function : Load |
102 | //purpose : |
103 | //======================================================================= |
104 | |
105 | void ShapeFix_Wireframe::Load(const TopoDS_Shape& shape) |
106 | { |
107 | ClearStatuses(); |
108 | myShape = shape; |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : FixWireGaps |
113 | //purpose : |
114 | //======================================================================= |
115 | |
116 | Standard_Boolean ShapeFix_Wireframe::FixWireGaps() |
117 | { |
118 | myStatusWireGaps = ShapeExtend::EncodeStatus( ShapeExtend_OK ); |
119 | if (myShape.IsNull()) return Standard_False; |
120 | |
121 | if (Context().IsNull()) SetContext(new ShapeBuild_ReShape); |
122 | else |
123 | { |
124 | TopoDS_Shape shape = myShape; |
125 | myShape.Nullify(); |
126 | myShape = Context()->Apply(shape); |
127 | } |
128 | |
129 | Standard_Real prec = (Precision()>0.)? Precision() : Precision::Confusion(); |
130 | TopTools_DataMapOfShapeShape cont; |
131 | if ( myShape.ShapeType() == TopAbs_COMPOUND ) |
132 | { |
133 | Standard_Boolean locModified = Standard_False; |
134 | TopoDS_Compound C; |
135 | BRep_Builder B; |
136 | B.MakeCompound ( C ); |
137 | TopoDS_Shape savShape = myShape; |
138 | for ( TopoDS_Iterator it(savShape); it.More(); it.Next() ) |
139 | { |
140 | TopoDS_Shape shape1 = it.Value(); |
141 | TopLoc_Location L = shape1.Location(),nullLoc; |
142 | shape1.Location ( nullLoc ); |
143 | TopoDS_Shape res; |
144 | if ( cont.IsBound ( shape1 ) ) |
145 | { |
146 | res = cont.Find ( shape1 ).Oriented ( shape1.Orientation() ); |
147 | } |
148 | else |
149 | { |
150 | myShape = shape1; |
151 | FixWireGaps(); |
152 | res = Shape(); |
153 | cont.Bind(myShape,res); |
154 | } |
155 | if ( ! res.IsSame ( shape1 ) ) locModified = Standard_True; |
156 | res.Location ( L ); |
157 | B.Add ( C, res ); |
158 | |
159 | } |
160 | if (locModified ) |
161 | { |
162 | C.Orientation(savShape.Orientation()); |
163 | Context()->Replace(savShape,C); |
164 | } |
165 | myShape = Context()->Apply(savShape); |
166 | return StatusWireGaps(ShapeExtend_DONE); |
167 | } |
168 | Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire; |
169 | sfw->SetContext(Context()); |
170 | sfw->SetPrecision(prec); |
171 | |
172 | TopoDS_Face face; |
173 | for (TopExp_Explorer anExpf1(myShape,TopAbs_FACE); anExpf1.More(); anExpf1.Next()) |
174 | { |
175 | //smh#8 |
176 | TopoDS_Shape tmpF = Context()->Apply(anExpf1.Current()); |
177 | face = TopoDS::Face(tmpF); |
178 | if (face.Orientation()==TopAbs_REVERSED) face.Orientation(TopAbs_FORWARD); |
179 | for (TopoDS_Iterator itw(face); itw.More(); itw.Next()) |
180 | { |
181 | if(itw.Value().ShapeType() != TopAbs_WIRE) |
182 | continue; |
183 | //smh#8 |
184 | TopoDS_Shape tmpW = Context()->Apply(itw.Value()); |
185 | sfw->Init(TopoDS::Wire(tmpW), face, prec); |
186 | sfw->FixReorder(); |
187 | sfw->FixGaps3d(); |
188 | if (sfw->StatusGaps3d(ShapeExtend_DONE)) |
189 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
190 | if (sfw->StatusGaps3d(ShapeExtend_FAIL)) |
191 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
192 | sfw->FixGaps2d(); |
193 | if (sfw->StatusGaps2d(ShapeExtend_DONE)) |
194 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
195 | if (sfw->StatusGaps2d(ShapeExtend_FAIL)) |
196 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL2 ); |
197 | } |
198 | } |
199 | |
200 | //============================================================ |
201 | //Author : enk |
202 | //Purpose: This block fixing a 3d wire which not lie on plane |
203 | // Part 1 |
204 | //============================================================ |
205 | for (TopExp_Explorer expw(myShape,TopAbs_WIRE,TopAbs_FACE); expw.More(); expw.Next()) |
206 | { |
207 | TopoDS_Shape tmpW = Context()->Apply(expw.Current()); |
208 | sfw->Load(TopoDS::Wire(tmpW)); |
209 | sfw->SetPrecision(prec); |
210 | sfw->FixReorder(); |
211 | sfw->FixGaps3d(); |
212 | if (sfw->StatusGaps3d(ShapeExtend_DONE)) |
213 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
214 | if (sfw->StatusGaps3d(ShapeExtend_FAIL)) |
215 | myStatusWireGaps |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
216 | } |
217 | //End Part1======================================================== |
218 | |
219 | if (StatusWireGaps(ShapeExtend_DONE)) |
220 | { |
221 | |
222 | myShape = Context()->Apply(myShape); |
223 | |
224 | ShapeFix::SameParameter(myShape,Standard_False); |
225 | |
226 | TopoDS_Wire wire; |
227 | Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge; |
228 | for (TopExp_Explorer anExpf2(myShape,TopAbs_FACE); anExpf2.More(); anExpf2.Next()) |
229 | { |
230 | face = TopoDS::Face(anExpf2.Current()); |
231 | if (face.Orientation()==TopAbs_REVERSED) face.Orientation(TopAbs_FORWARD); |
232 | for (TopoDS_Iterator itw(face); itw.More(); itw.Next()) |
233 | { |
234 | if(itw.Value().ShapeType() != TopAbs_WIRE) |
235 | continue; |
236 | wire = TopoDS::Wire(itw.Value()); |
237 | sfw->Init(wire, face, prec); |
238 | sfw->FixReorder(); |
239 | sfw->FixSelfIntersection(); |
240 | for (TopoDS_Iterator ite(wire); ite.More(); ite.Next()) |
241 | sfe->FixVertexTolerance(TopoDS::Edge(ite.Value())); |
242 | } |
243 | } |
244 | |
245 | // enk Part 2 |
246 | for (TopExp_Explorer expw2(myShape,TopAbs_WIRE,TopAbs_FACE); expw2.More(); expw2.Next()) |
247 | { |
248 | wire = TopoDS::Wire(expw2.Current()); |
249 | sfw->Load(wire); |
250 | sfw->SetPrecision(prec); |
251 | sfw->FixReorder(); |
252 | sfw->FixSelfIntersection(); |
253 | for (TopoDS_Iterator ite(wire); ite.More(); ite.Next()) |
254 | sfe->FixVertexTolerance(TopoDS::Edge(ite.Value())); |
255 | |
256 | } |
257 | // End Part 2 |
258 | |
259 | return Standard_True; |
260 | } |
261 | |
262 | return Standard_False; |
263 | } |
264 | |
265 | //======================================================================= |
266 | //function : JoinEdges (static) |
267 | //purpose : used in FixSmallEdges |
268 | //======================================================================= |
269 | |
270 | static Standard_Boolean JoinEdges(const TopoDS_Edge& E1, |
271 | const TopoDS_Edge& E2, |
272 | TopoDS_Edge& E3, |
273 | const TopTools_ListOfShape& faces) |
274 | { |
275 | Standard_Boolean ReplaceFirst = Standard_True; |
276 | ShapeAnalysis_Edge sae; |
277 | Handle(Geom_Curve) c3d1,c3d2; |
278 | Handle(Geom2d_Curve) c2d1,c2d2; //TopTools |
279 | TopoDS_Edge newedge,newedge1; |
280 | E3 = newedge1; |
281 | TopoDS_Vertex V11 = sae.FirstVertex(E1); |
282 | TopoDS_Vertex V12 = sae.LastVertex(E1); |
283 | TopoDS_Vertex V21 = sae.FirstVertex(E2); |
284 | TopoDS_Vertex V22 = sae.LastVertex(E2); |
285 | |
286 | |
287 | Standard_Boolean isSame = (V11.IsSame(V12) || V22.IsSame(V21)); |
288 | BRep_Builder B; |
289 | B.MakeEdge(newedge); |
290 | Standard_Real cf1,cf2,cl1,cl2,first1,first2,last1,last2; |
291 | newedge.Orientation(TopAbs_FORWARD); |
292 | try |
293 | { |
294 | OCC_CATCH_SIGNALS |
295 | if(!sae.Curve3d(E1,c3d1,cf1,cl1,Standard_False )) return ReplaceFirst; |
296 | if(!sae.Curve3d(E2,c3d2,cf2,cl2,Standard_False )) return ReplaceFirst; |
297 | |
298 | |
299 | B.Add(newedge,V11.Oriented(TopAbs_FORWARD)); |
300 | B.Add(newedge,V22.Oriented(TopAbs_REVERSED)); |
301 | |
302 | Handle(Geom_Curve) CRes; |
303 | Standard_Boolean isRev1,isRev2; |
304 | // Standard_Real newf,newl; |
305 | if(!ShapeConstruct::JoinCurves(c3d1,c3d2,E1.Orientation(),E2.Orientation(),cf1, cl1,cf2, cl2,CRes,isRev1,isRev2)) |
306 | return ReplaceFirst; |
307 | // if(isRev1 || isRev2) |
308 | if(!isSame && (isRev1 || isRev2)) |
309 | return ReplaceFirst; |
310 | ReplaceFirst = (!isRev1); |
311 | |
312 | Standard_Real newf = cf1; |
313 | Standard_Real newl = cl1 + cl2 - cf2; |
314 | TopAbs_Orientation OrEdge1 = E1.Orientation(); |
315 | TopAbs_Orientation OrEdge2 = E2.Orientation(); |
316 | Standard_Boolean ismanifold =(OrEdge1 == TopAbs_FORWARD || OrEdge1 == TopAbs_REVERSED); |
317 | Standard_Boolean ismanifold2 = (OrEdge2 == TopAbs_FORWARD || OrEdge2 == TopAbs_REVERSED); |
318 | if(ismanifold != ismanifold2) |
319 | return ReplaceFirst; |
320 | |
321 | if(ismanifold) { |
322 | |
323 | OrEdge1 = ( (!isRev1 && E1.Orientation() == TopAbs_FORWARD) || |
324 | (isRev1 && E1.Orientation() == TopAbs_REVERSED) ? TopAbs_FORWARD :TopAbs_REVERSED); |
325 | OrEdge2 = ( (!isRev2 && E2.Orientation() == TopAbs_FORWARD) || |
326 | (isRev2 && E2.Orientation() == TopAbs_REVERSED) ? TopAbs_FORWARD :TopAbs_REVERSED); |
327 | } |
328 | B.UpdateEdge(newedge,CRes,Max(BRep_Tool::Tolerance(E1),BRep_Tool::Tolerance(E2))); |
329 | Standard_Real fp= CRes->FirstParameter(); |
330 | Standard_Real lp= CRes->LastParameter(); |
331 | if(fp > newf) newf = fp; |
332 | if(lp < newl) newl = lp; |
333 | B.Range(newedge,newf,newl); |
334 | |
335 | //merging pcurves |
336 | for(TopTools_ListIteratorOfListOfShape iter(faces); iter.More(); iter.Next()) |
337 | { |
338 | TopoDS_Face face = TopoDS::Face(iter.Value()); |
339 | if(!sae.PCurve ( E1, face, c2d1, first1, last1, Standard_False )) return ReplaceFirst; |
340 | if(!sae.PCurve ( E2, face, c2d2, first2, last2, Standard_False )) return ReplaceFirst; |
341 | |
342 | Handle(Geom2d_Curve) C2dRes; |
343 | Standard_Boolean isRev12,isRev22; |
344 | if(!ShapeConstruct::JoinCurves(c2d1,c2d2,OrEdge1,OrEdge2,first1, last1,first2, last2,C2dRes,isRev12,isRev22,isSame)) |
345 | return ReplaceFirst; |
346 | |
347 | if(ismanifold && (!isSame && (isRev12 || isRev22))) |
348 | return ReplaceFirst; |
349 | |
350 | if(isRev12) |
351 | ReplaceFirst = Standard_False; |
352 | Standard_Real fp2d = C2dRes->FirstParameter(); |
353 | Standard_Real lp2d = C2dRes->LastParameter(); |
354 | //B.UpdateEdge(newedge,C2dRes,face,0); |
355 | Standard_Real newf1 = first1; |
356 | Standard_Real newl1 = last1 + (last2 - first2); |
357 | if(fp2d > newf1) newf1 = fp2d; |
358 | if(lp2d < newl1) newl1 = lp2d; |
359 | |
360 | // dealing with seams: the same again |
361 | if(sae.IsSeam(E1,face) && sae.IsSeam(E2,face)) |
362 | { |
363 | Handle(Geom2d_Curve) c2d12,c2d22; |
364 | //smh#8 |
365 | TopoDS_Shape tmpE1 = E1.Reversed(), |
366 | tmpE2 = E2.Reversed(); |
367 | TopoDS_Edge E1t = TopoDS::Edge(tmpE1); |
368 | TopoDS_Edge E2t = TopoDS::Edge(tmpE2); |
369 | sae.PCurve ( E1t, face, c2d12, first1, last1, Standard_False ); |
370 | sae.PCurve ( E2t, face, c2d22, first2, last2, Standard_False ); |
371 | |
372 | Handle(Geom2d_Curve) C2dRes2; |
373 | if(!ShapeConstruct::JoinCurves(c2d12,c2d22,OrEdge1,OrEdge2,first1, last1,first2, last2,C2dRes2,isRev12,isRev22,isSame)) |
374 | return ReplaceFirst; |
375 | if(!isSame && (isRev1 || isRev2)) |
376 | return ReplaceFirst; |
377 | B.UpdateEdge(newedge,C2dRes,C2dRes2,face,0); |
378 | } |
379 | else if(sae.IsSeam(E1,face) || sae.IsSeam(E2,face)) return ReplaceFirst; |
380 | else if(!sae.IsSeam(E1,face) && !sae.IsSeam(E2,face)) |
381 | B.UpdateEdge(newedge,C2dRes,face,0); |
382 | B.Range(newedge,face,newf1,newl1); |
383 | if(!ismanifold) |
384 | newedge.Orientation(ReplaceFirst ? OrEdge1 :OrEdge2 ); |
385 | } |
386 | B.SameRange(newedge,Standard_False); |
387 | |
388 | E3 = newedge; |
389 | return ReplaceFirst; |
390 | } |
391 | catch ( Standard_Failure ) |
392 | { |
393 | #ifdef DEB |
394 | cout<<"Error: ShapeFix_Wireframe::FixSmallEdges: JoinEdges: Exception in GeomConvert_CompCurveToBSplineCurve: "; |
395 | Standard_Failure::Caught()->Print(cout); cout<<endl; |
396 | #endif |
397 | return ReplaceFirst; |
398 | } |
399 | return ReplaceFirst; |
400 | } |
401 | |
402 | //======================================================================= |
403 | //function : FixSmallEdges |
404 | //purpose : |
405 | //======================================================================= |
406 | |
407 | Standard_Boolean ShapeFix_Wireframe::FixSmallEdges() |
408 | { |
409 | myStatusSmallEdges = ShapeExtend::EncodeStatus( ShapeExtend_OK ); |
410 | if (myShape.IsNull()) return Standard_False; |
411 | |
412 | if (Context().IsNull()) SetContext(new ShapeBuild_ReShape); |
413 | else |
414 | { |
415 | TopoDS_Shape shape = myShape; |
416 | myShape.Nullify(); |
417 | myShape = Context()->Apply(shape); |
418 | } |
419 | TopTools_DataMapOfShapeShape cont; |
420 | if ( myShape.ShapeType() == TopAbs_COMPOUND ) |
421 | { |
422 | Standard_Boolean locModified = Standard_False; |
423 | TopoDS_Compound C; |
424 | BRep_Builder B; |
425 | B.MakeCompound ( C ); |
426 | TopoDS_Shape savShape = myShape; |
427 | for ( TopoDS_Iterator it(savShape); it.More(); it.Next() ) |
428 | { |
429 | TopoDS_Shape shape1 = it.Value(); |
430 | TopLoc_Location L = shape1.Location(),nullLoc; |
431 | shape1.Location ( nullLoc ); |
432 | TopoDS_Shape res; |
433 | if ( cont.IsBound ( shape1 ) ) |
434 | { |
435 | res = cont.Find ( shape1 ).Oriented ( shape1.Orientation() ); |
436 | } |
437 | else |
438 | { |
439 | myShape = shape1; |
440 | FixSmallEdges(); |
441 | res = Shape(); |
442 | cont.Bind(myShape,res); |
443 | } |
444 | if ( ! res.IsSame ( shape1 ) ) locModified = Standard_True; |
445 | res.Location ( L ); |
446 | B.Add ( C, res ); |
447 | |
448 | } |
449 | if (locModified ) |
450 | { |
451 | C.Orientation(savShape.Orientation()); |
452 | Context()->Replace(savShape,C); |
453 | } |
454 | myShape = Context()->Apply(savShape); |
455 | return StatusSmallEdges( ShapeExtend_DONE ); |
456 | } |
457 | TopTools_MapOfShape theSmallEdges, theMultyEdges; |
458 | TopTools_DataMapOfShapeListOfShape theEdgeToFaces,theFaceWithSmall; |
459 | CheckSmallEdges ( theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges); |
460 | MergeSmallEdges ( theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges); |
461 | return StatusSmallEdges( ShapeExtend_DONE ); |
462 | } |
463 | |
464 | //======================================================================= |
465 | //function : CheckSmallEdges |
466 | //purpose : |
467 | //======================================================================= |
468 | #include <BRepBuilderAPI_MakeFace.hxx> |
469 | #include <TopExp.hxx> |
470 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
471 | Standard_Boolean ShapeFix_Wireframe::CheckSmallEdges(TopTools_MapOfShape& theSmallEdges, |
472 | TopTools_DataMapOfShapeListOfShape& theEdgeToFaces, |
473 | TopTools_DataMapOfShapeListOfShape& theFaceWithSmall, |
474 | TopTools_MapOfShape& theMultyEdges) |
475 | { |
476 | TopoDS_Face face; |
477 | TopoDS_Edge edge; |
478 | ShapeAnalysis_Wire SAW; |
479 | |
480 | for (TopExp_Explorer anExpf1(myShape,TopAbs_FACE); anExpf1.More(); anExpf1.Next()) |
481 | { |
482 | TopTools_ListOfShape theEdgeList; |
483 | TopoDS_Face facet = TopoDS::Face(anExpf1.Current()); |
484 | face = facet; |
485 | if (facet.Orientation()==TopAbs_REVERSED) face = TopoDS::Face(facet.Oriented(TopAbs_FORWARD)); |
486 | for (TopoDS_Iterator itw(face); itw.More(); itw.Next()) |
487 | { |
488 | if(itw.Value().ShapeType() != TopAbs_WIRE) |
489 | continue; |
490 | TopoDS_Wire aW = TopoDS::Wire(itw.Value()); |
491 | Handle(ShapeExtend_WireData) aswd = new ShapeExtend_WireData(aW,Standard_True,Standard_False); |
492 | SAW.Init(aswd,face,Precision()); |
493 | // pnd protection on seam edges |
494 | TopTools_DataMapOfShapeInteger EdgeMap; |
495 | Standard_Integer i; |
496 | for (i=1; i<=SAW.NbEdges(); i++) |
497 | { |
498 | edge = SAW.WireData()->Edge(i); |
499 | if (EdgeMap.IsBound(edge)) |
500 | EdgeMap.ChangeFind(edge)++; |
501 | else |
502 | EdgeMap.Bind(edge,1); |
503 | } |
504 | |
505 | for ( i=1; i<=SAW.NbEdges(); i++) |
506 | { |
507 | edge = SAW.WireData()->Edge(i); |
508 | if(EdgeMap.Find(edge)!=1) |
509 | { |
510 | if(!SAW.WireData()->IsSeam(i)) |
511 | theMultyEdges.Add(edge); |
512 | continue; |
513 | } |
514 | // Append current face to the list |
515 | if (theEdgeToFaces.IsBound(edge)) |
516 | { |
517 | theEdgeToFaces(edge).Append(facet); |
518 | } |
519 | else |
520 | { |
521 | TopTools_ListOfShape theFaceList; |
522 | theFaceList.Append(facet); |
523 | theEdgeToFaces.Bind(edge,theFaceList); |
524 | } |
525 | // Check if current edge is small |
526 | if (theSmallEdges.Contains(edge)) theEdgeList.Append(edge); |
527 | else if (SAW.CheckSmall(i,Precision())) |
528 | { |
529 | theSmallEdges.Add(edge); |
530 | theEdgeList.Append(edge); |
531 | } |
532 | } |
533 | } |
534 | // Add current face to the map if has small edges |
535 | if (theEdgeList.Extent()) theFaceWithSmall.Bind(facet,theEdgeList); |
536 | } |
537 | |
538 | //======================================================================== |
539 | // Author : enk |
540 | // Purpose: Analizing of shape for small edges , if edge don't lie on face |
541 | //======================================================================== |
542 | for (TopExp_Explorer expw1(myShape,TopAbs_WIRE,TopAbs_FACE); expw1.More(); expw1.Next()) |
543 | { |
544 | SAW.SetPrecision(Precision()); |
545 | TopTools_DataMapOfShapeInteger EdgeMap; |
546 | Standard_Integer i; |
547 | TopoDS_Wire theWire=TopoDS::Wire(expw1.Current()); |
548 | TopTools_ListOfShape theEdgeList; |
549 | SAW.Load(theWire); |
550 | if (!SAW.IsLoaded()) |
551 | { |
552 | return Standard_False; |
553 | } |
554 | for (i=1; i<=SAW.NbEdges(); i++) |
555 | { |
556 | edge = SAW.WireData()->Edge(i); |
557 | if (EdgeMap.IsBound(edge)) |
558 | EdgeMap.ChangeFind(edge)++; |
559 | else |
560 | EdgeMap.Bind(edge,1); |
561 | } |
562 | |
563 | for ( i=1; i<=SAW.NbEdges(); i++) |
564 | { |
565 | edge = SAW.WireData()->Edge(i); |
566 | if(EdgeMap.Find(edge)!=1) |
567 | { |
568 | if(!SAW.WireData()->IsSeam(i)) |
569 | theMultyEdges.Add(edge); |
570 | continue; |
571 | } |
572 | |
573 | // Check if current edge is small |
574 | if (theSmallEdges.Contains(edge)) theEdgeList.Append(edge); |
575 | else if (SAW.CheckSmall(i,Precision())) |
576 | { |
577 | theSmallEdges.Add(edge); |
578 | theEdgeList.Append(edge); |
579 | } |
580 | } |
581 | |
582 | } |
583 | return (!theSmallEdges.IsEmpty()); |
584 | |
585 | } |
586 | |
587 | //======================================================================= |
588 | //function : MergeSmallEdges |
589 | //purpose : |
590 | //======================================================================= |
591 | |
592 | Standard_Boolean ShapeFix_Wireframe::MergeSmallEdges(TopTools_MapOfShape& theSmallEdges, |
593 | TopTools_DataMapOfShapeListOfShape& theEdgeToFaces, |
594 | TopTools_DataMapOfShapeListOfShape& theFaceWithSmall, |
595 | TopTools_MapOfShape& theMultyEdges, |
596 | const Standard_Boolean theModeDrop, |
597 | const Standard_Real theLimitAngle) |
598 | { |
599 | Standard_Boolean aModLimitAngle = (theLimitAngle >-1.0 || myLimitAngle > -1.0); |
600 | Standard_Real aLimitAngle = Max(theLimitAngle,myLimitAngle); |
601 | |
602 | Standard_Boolean aModeDrop = theModeDrop || myModeDrop; |
603 | TopTools_DataMapOfShapeShape theNewVertices; |
604 | if (!theSmallEdges.IsEmpty()) |
605 | { |
606 | |
607 | Handle(ShapeFix_Wire) SFW = new ShapeFix_Wire; |
608 | SFW->SetContext(Context()); |
609 | ShapeAnalysis_Edge SAE; |
610 | TopoDS_Edge edge1, edge2, edge3; |
611 | // Iterate on map of faces with small edges |
612 | TopExp_Explorer anExpf2(myShape,TopAbs_FACE); |
613 | for (; anExpf2.More(); anExpf2.Next()) |
614 | { |
615 | if (theFaceWithSmall.IsBound(anExpf2.Current())) |
616 | { |
617 | if (theFaceWithSmall(anExpf2.Current()).Extent()) |
618 | { |
619 | //smh#8 |
620 | TopoDS_Shape tmpShape = Context()->Apply(anExpf2.Current()); |
621 | TopoDS_Face facet = TopoDS::Face(tmpShape); |
622 | if(!facet.IsSame(anExpf2.Current())) |
623 | { //gka |
624 | TopExp_Explorer aExpEdge(anExpf2.Current(),TopAbs_EDGE); |
625 | for( ; aExpEdge.More(); aExpEdge.Next()) |
626 | { |
627 | TopoDS_Shape newEdge; |
628 | Standard_Integer stat = Context()->Status(aExpEdge.Current(),newEdge,Standard_True); |
629 | if(stat > 0 ) |
630 | { |
631 | if(theSmallEdges.Contains(aExpEdge.Current())) |
632 | { |
633 | theSmallEdges.Remove(aExpEdge.Current()); |
634 | theSmallEdges.Add(newEdge); |
635 | } |
636 | if(theEdgeToFaces.IsBound(aExpEdge.Current())) |
637 | { |
638 | TopTools_ListOfShape aListFaces; |
639 | aListFaces = theEdgeToFaces.Find(aExpEdge.Current()); |
640 | theEdgeToFaces.UnBind(aExpEdge.Current()); |
641 | theEdgeToFaces.Bind(newEdge,aListFaces); |
642 | |
643 | } |
644 | } |
645 | } |
646 | } |
647 | TopoDS_Face face = facet; |
648 | //if (face.Orientation()==TopAbs_REVERSED) |
649 | // face = TopoDS::Face(facet.Oriented(TopAbs_FORWARD)); |
650 | for (TopoDS_Iterator itw(face); itw.More(); itw.Next()) |
651 | { |
652 | if(itw.Value().ShapeType() != TopAbs_WIRE) continue; |
653 | TopoDS_Wire aWire = TopoDS::Wire(itw.Value()); |
654 | if (face.Orientation()==TopAbs_REVERSED) |
655 | face = TopoDS::Face(facet.Oriented(TopAbs_FORWARD)); |
656 | Handle(ShapeExtend_WireData) aswd = new ShapeExtend_WireData(aWire,Standard_True,Standard_False); |
657 | //SFW->Load(aWire); |
658 | SFW->Load(aswd); |
659 | SFW->FixReorder(); |
660 | Standard_Integer prev, next, index = 1; |
661 | |
662 | while (index <= SFW->WireData()->NbEdges() && SFW->NbEdges()>1) |
663 | { |
664 | prev = (index==1)? SFW->WireData()->NbEdges() : index-1; |
665 | next = (index==SFW->WireData()->NbEdges())? 1 : index+1; |
666 | edge1 = SFW->WireData()->Edge(prev); |
667 | edge2 = SFW->WireData()->Edge(index); |
668 | edge3 = SFW->WireData()->Edge(next); |
669 | |
670 | //gka protection against joining seem edge |
671 | if(edge2.IsSame(edge1) || edge2.IsSame(edge3)) |
672 | { |
673 | //if(BRep_Tool::IsClosed(edge2,face)) { |
674 | index++; |
675 | continue; |
676 | } |
677 | |
678 | Standard_Boolean isSeam = SFW->WireData()->IsSeam(index); |
679 | Standard_Boolean isSeam1 = SFW->WireData()->IsSeam(prev); |
680 | Standard_Boolean isSeam2 = SFW->WireData()->IsSeam(next); |
681 | if (theSmallEdges.Contains(edge2)) |
682 | { |
683 | // Middle edge is small - choose a pair of edges to join |
684 | Standard_Boolean IsAnyJoin = (edge1.IsSame(edge3)); |
685 | Standard_Boolean take_next = IsAnyJoin; //Standard_False; |
686 | Standard_Boolean isLimAngle = Standard_False; |
687 | Handle(Geom_Curve) C1, C2, C3; |
688 | Standard_Real aux, last1, first2, last2, first3; |
689 | Standard_Real Ang1 = 0., Ang2 =0.; |
690 | if (SAE.Curve3d(edge1,C1,aux,last1) && |
691 | SAE.Curve3d(edge2,C2,first2,last2) && |
692 | SAE.Curve3d(edge3,C3,first3,aux)) |
693 | { |
694 | // Compare angles between edges |
695 | //Standard_Real Ang1, Ang2; |
696 | gp_Vec Vec1, Vec2; gp_Pnt P; |
697 | C1->D1(last1,P,Vec1); |
698 | C2->D1(first2,P,Vec2); |
699 | if ( edge1.Orientation() == TopAbs_REVERSED ) Vec1.Reverse(); |
700 | if ( edge2.Orientation() == TopAbs_REVERSED ) Vec2.Reverse(); |
08cd2f6b |
701 | Standard_Real tol2 = Precision::SquareConfusion(); |
7fd59977 |
702 | if ( Vec1.SquareMagnitude() < tol2 || |
c6541a0c |
703 | Vec2.SquareMagnitude() < tol2 ) Ang1 = M_PI/2.; |
7fd59977 |
704 | else Ang1 = Abs(Vec1.Angle(Vec2)); |
705 | C2->D1(last2,P,Vec1); |
706 | C3->D1(first3,P,Vec2); |
707 | if ( edge2.Orientation() == TopAbs_REVERSED ) Vec1.Reverse(); |
708 | if ( edge3.Orientation() == TopAbs_REVERSED ) Vec2.Reverse(); |
709 | if ( Vec1.SquareMagnitude() < tol2 || |
c6541a0c |
710 | Vec2.SquareMagnitude() < tol2 ) Ang2 = M_PI/2.; |
7fd59977 |
711 | else Ang2 = Abs(Vec1.Angle(Vec2)); |
712 | //isLimAngle = (theLimitAngle != -1 && Min(Ang1,Ang2) > theLimitAngle); |
713 | //take_next = (Ang2<Ang1); |
714 | //if (take_next) { edge1 = edge2; edge2 = edge3; } |
715 | } |
716 | //if(theLimitAngle != -1 && Ang1 > theLimitAngle && Ang2 >theLimitAngle) { |
717 | // index++; continue; |
718 | //} |
719 | |
720 | // Check if edges lay on the same faces |
721 | if(theMultyEdges.Contains(edge1) || theMultyEdges.Contains(edge2)) |
722 | { //?????? |
723 | index++; |
724 | continue; |
725 | } |
726 | TopTools_ListOfShape theList1,theList2,theList3; |
727 | if(theEdgeToFaces.IsBound(edge1)) |
728 | theList1 = theEdgeToFaces(edge1); |
729 | if(theEdgeToFaces.IsBound(edge2)) |
730 | theList2 = theEdgeToFaces(edge2); |
731 | if(theEdgeToFaces.IsBound(edge3)) |
732 | theList3 = theEdgeToFaces(edge3); |
733 | Standard_Boolean same_set = Standard_False; |
734 | |
735 | //gka protection against joining seem edges with other edges |
736 | Standard_Boolean same_set1 = (theList1.Extent()==theList2.Extent() && |
737 | ((!isSeam && !isSeam1)|| (isSeam && isSeam1))); //gka |
738 | Standard_Boolean same_set2 = (theList3.Extent()==theList2.Extent() && |
739 | ((!isSeam && !isSeam2)|| (isSeam && isSeam2))); |
740 | TopTools_MapOfShape theSetOfFaces; |
741 | for (TopTools_ListIteratorOfListOfShape itf1(theList2); |
742 | itf1.More(); itf1.Next()) |
743 | theSetOfFaces.Add(itf1.Value()); |
744 | if (same_set1) |
745 | { |
746 | // Add all faces of the first edge to the current set |
747 | for (TopTools_ListIteratorOfListOfShape itf2(theList1); |
748 | (itf2.More() && same_set1); itf2.Next()) |
749 | same_set1 = theSetOfFaces.Contains(itf2.Value()); |
750 | } |
751 | if (same_set2) |
752 | { |
753 | // Add all faces of the first edge to the current set |
754 | for (TopTools_ListIteratorOfListOfShape itf2(theList3); |
755 | (itf2.More() && same_set2); itf2.Next()) |
756 | same_set2 = theSetOfFaces.Contains(itf2.Value()); |
757 | } |
758 | if(same_set1 && same_set2) |
759 | { |
760 | same_set = Standard_True; |
761 | if(fabs(Ang2-Ang1) >Precision::Angular()) |
762 | take_next = (Ang2<Ang1); |
763 | if (take_next) |
764 | { |
765 | edge1 = edge2; edge2 = edge3; |
766 | } |
767 | isLimAngle = (aModLimitAngle && Min(Ang1,Ang2) > aLimitAngle); |
768 | } |
769 | else if(same_set1 && !same_set2) |
770 | { |
771 | isLimAngle = (aModLimitAngle && Ang1 > aLimitAngle); |
772 | same_set = Standard_True; |
773 | } |
774 | else if(!same_set1 && same_set2) |
775 | { |
776 | same_set = Standard_True; |
777 | isLimAngle = (aModLimitAngle && Ang2 > aLimitAngle); |
778 | edge1 = edge2; edge2 = edge3; |
779 | take_next = Standard_True; |
780 | } |
781 | if (same_set && !isLimAngle ) |
782 | { |
783 | // Merge current pair of edges |
784 | //gka protection against crossing seem on second face |
785 | Standard_Boolean isNeedJoin = Standard_True;//Standard_False; |
786 | for(TopTools_ListIteratorOfListOfShape aItF(theList2); aItF.More() && isNeedJoin; aItF.Next()) |
787 | { |
788 | if(aItF.Value().IsSame(anExpf2.Current())) continue; |
789 | TopoDS_Shape aF = Context()->Apply(aItF.Value()); |
790 | //aF = aF.Oriented(TopAbs_FORWARD); |
791 | for(TopoDS_Iterator aIw(aF); aIw.More(); aIw.Next()) |
792 | { |
793 | if(aIw.Value().ShapeType() != TopAbs_WIRE) continue; |
794 | TopoDS_Wire wt = TopoDS::Wire(aIw.Value()); |
795 | Handle(ShapeFix_Wire) SFW1 = new ShapeFix_Wire; |
796 | SFW1->Load(wt); |
797 | SFW1->FixReorder(); |
798 | Handle(ShapeExtend_WireData) atmpswd = SFW1->WireData(); |
799 | Standard_Integer ind1 = atmpswd->Index(edge1); |
800 | Standard_Integer ind2 = atmpswd->Index(edge2); |
801 | if(ind1 && ind2) |
802 | { |
803 | isNeedJoin = ((ind1 -ind2) ==1 || (ind2 == atmpswd->NbEdges() && ind1 ==1)); |
804 | break; |
805 | } |
806 | } |
807 | } |
808 | Standard_Boolean ReplaceFirst = Standard_True; |
809 | if(isNeedJoin) |
810 | { |
811 | |
812 | TopTools_ListOfShape aListF; |
813 | for(TopTools_ListIteratorOfListOfShape aItlF(theList2); aItlF.More(); aItlF.Next()) |
814 | { |
815 | TopoDS_Shape tmpF = Context()->Apply(aItlF.Value()); |
816 | aListF.Append(tmpF); |
817 | } |
818 | ReplaceFirst = JoinEdges(edge1,edge2,edge3,aListF); |
819 | } |
820 | else edge3 = TopoDS_Edge(); |
821 | if (edge3.IsNull()) |
822 | { |
823 | index++; |
824 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
825 | } |
826 | else |
827 | { |
828 | // Record vertex replacements in the map |
829 | TopoDS_Vertex oldV1 = SAE.FirstVertex(edge3), |
830 | oldV2 = SAE.LastVertex(edge3); |
831 | if (!theNewVertices.IsBound(oldV1)) |
832 | //smh#8 |
833 | { |
834 | TopoDS_Shape emptyCopiedV1 = oldV1.EmptyCopied(); |
835 | theNewVertices.Bind(oldV1,TopoDS::Vertex(emptyCopiedV1)); |
836 | } |
837 | if (!oldV1.IsSame(oldV2)) |
838 | if (!theNewVertices.IsBound(oldV2)) |
839 | //smh#8 |
840 | { |
841 | TopoDS_Shape emptyCopiedV2 = oldV2.EmptyCopied(); |
842 | theNewVertices.Bind(oldV2,TopoDS::Vertex(emptyCopiedV2)); |
843 | } |
844 | |
845 | //To keep NM vertices belonging initial edges |
846 | TopoDS_Iterator aItv(edge1,Standard_False); |
847 | for( ; aItv.More(); aItv.Next()) { |
848 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
849 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
850 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
851 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,edge3,edge1); |
852 | BRep_Builder aB; |
853 | aB.Add(edge3,anewV); |
854 | Context()->Replace(aOldV,anewV); |
855 | } |
856 | } |
857 | |
858 | for(aItv.Initialize(edge2,Standard_False) ; aItv.More(); aItv.Next()) { |
859 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
860 | aItv.Value().Orientation() == TopAbs_EXTERNAL){ |
861 | BRep_Builder aB; |
862 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
863 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,edge3,edge2); |
864 | aB.Add(edge3,anewV); |
865 | Context()->Replace(aOldV,anewV); |
866 | } |
867 | } |
868 | |
869 | // Check for small resulting edge |
870 | Standard_Boolean newsmall = Standard_False; |
871 | ShapeAnalysis_Wire SAW; |
872 | SAW.Init(SFW->WireData(),face,Precision()); |
873 | // Make changes in WireData and Context |
874 | if(ReplaceFirst) |
875 | { |
876 | Context()->Replace(edge1,edge3); |
877 | Context()->Remove(edge2); |
878 | } |
879 | else |
880 | { |
881 | Context()->Replace(edge2,edge3); |
882 | Context()->Remove(edge1); |
883 | } |
884 | if (take_next) |
885 | { |
886 | SFW->WireData()->Set(edge3,next); |
887 | newsmall = SAW.CheckSmall(next,Precision()); |
888 | } |
889 | else |
890 | { |
891 | SFW->WireData()->Set(edge3,prev); |
892 | newsmall = SAW.CheckSmall(prev,Precision()); |
893 | } |
894 | SFW->WireData()->Remove(index); |
895 | // Process changes in maps |
896 | TopTools_ListOfShape theList; |
897 | theList.Append(theList2); |
898 | theEdgeToFaces.UnBind(edge1); |
899 | theEdgeToFaces.UnBind(edge2); |
900 | theEdgeToFaces.Bind(edge3,theList); |
901 | if (theSmallEdges.Contains(edge1)) theSmallEdges.Remove(edge1); |
902 | if (theSmallEdges.Contains(edge2)) theSmallEdges.Remove(edge2); |
903 | if (newsmall) theSmallEdges.Add(edge3); |
904 | for (TopTools_ListIteratorOfListOfShape itlf(theList); |
905 | itlf.More(); itlf.Next()) |
906 | { |
907 | TopoDS_Shape curface = itlf.Value(); |
908 | if (theFaceWithSmall.IsBound(curface)) |
909 | { |
910 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
911 | if (newsmall) theEdges.Append(edge3); |
912 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
913 | while (ite.More()) |
914 | { |
915 | TopoDS_Shape iedge = ite.Value(); |
916 | if (iedge.IsSame(edge1) || iedge.IsSame(edge2)) |
917 | theEdges.Remove(ite); |
918 | else ite.Next(); |
919 | } |
920 | // Remove face without small edges from the map |
921 | if (!theEdges.Extent()) theFaceWithSmall.UnBind(curface); |
922 | } |
923 | } |
924 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
925 | } |
926 | } |
927 | else if(aModeDrop) |
928 | { //gka |
929 | Handle(ShapeExtend_WireData) tempWire = new ShapeExtend_WireData(); |
930 | ShapeAnalysis_Wire tempSaw; |
931 | tempWire->Add(SFW->Wire()); |
932 | TopoDS_Edge remedge; |
933 | if (take_next) |
934 | remedge = edge1; |
935 | else remedge = edge2; |
936 | tempWire->Remove (index ); |
937 | tempSaw.Load(tempWire); |
938 | Standard_Integer newindex = (index <= tempSaw.NbEdges() ? index : 1); |
939 | tempSaw.CheckConnected(newindex,Precision()); |
940 | if(!tempSaw.LastCheckStatus(ShapeExtend_FAIL)) |
941 | { |
942 | SFW->WireData()->Remove (index ); |
943 | TopoDS_Edge tmpedge1 = tempWire->Edge(newindex); |
944 | TopoDS_Edge tmpedge2 = tempWire->Edge(newindex == 1 ? tempSaw.NbEdges() : (newindex- 1)); |
945 | TopTools_ListOfShape aL1; |
946 | if(theEdgeToFaces.IsBound(tmpedge1)) |
947 | aL1 = theEdgeToFaces.Find(tmpedge1); |
948 | TopTools_ListOfShape aL2; |
949 | if(theEdgeToFaces.IsBound(tmpedge2)) |
950 | aL2= theEdgeToFaces.Find(tmpedge2); |
951 | SFW->FixConnected(newindex <= SFW->NbEdges() ? newindex : 1,Precision()); |
952 | SFW->FixDegenerated(newindex <= SFW->NbEdges() ? newindex : 1); |
953 | TopoDS_Shape aTmpShape = Context()->Apply(tmpedge1); //for porting |
954 | TopoDS_Edge anewedge1 = TopoDS::Edge(aTmpShape); |
955 | aTmpShape = Context()->Apply(tmpedge2); |
956 | TopoDS_Edge anewedge2 = TopoDS::Edge(aTmpShape); |
957 | Context()->Remove(remedge); |
958 | if (theSmallEdges.Contains(remedge)) |
959 | theSmallEdges.Remove(remedge); |
960 | theEdgeToFaces.UnBind(remedge); |
961 | theEdgeToFaces.UnBind(tmpedge1); |
962 | theEdgeToFaces.UnBind(tmpedge2); |
963 | theEdgeToFaces.Bind(anewedge1,aL1); |
964 | theEdgeToFaces.Bind(anewedge2,aL2); |
965 | if (theSmallEdges.Contains(tmpedge1)) |
966 | { |
967 | theSmallEdges.Remove(tmpedge1); |
968 | theSmallEdges.Add(anewedge1); |
969 | for (TopTools_ListIteratorOfListOfShape itlf(aL1); |
970 | itlf.More(); itlf.Next()) |
971 | { |
972 | TopoDS_Shape curface = itlf.Value(); |
973 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
974 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
975 | while (ite.More()) |
976 | { |
977 | TopoDS_Shape iedge = ite.Value(); |
978 | if (iedge.IsSame(tmpedge1)) |
979 | { |
980 | theEdges.Remove(ite); |
981 | theEdges.Append(anewedge1); |
982 | } |
983 | else ite.Next(); |
984 | } |
985 | } |
986 | } |
987 | if (theSmallEdges.Contains(tmpedge2)) |
988 | { |
989 | theSmallEdges.Remove(tmpedge2); |
990 | theSmallEdges.Add(anewedge2); |
991 | for (TopTools_ListIteratorOfListOfShape itlf(aL2); |
992 | itlf.More(); itlf.Next()) |
993 | { |
994 | TopoDS_Shape curface = itlf.Value(); |
995 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
996 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
997 | while (ite.More()) |
998 | { |
999 | TopoDS_Shape iedge = ite.Value(); |
1000 | if (iedge.IsSame(tmpedge2)) |
1001 | { |
1002 | theEdges.Remove(ite); |
1003 | theEdges.Append(anewedge2); |
1004 | } |
1005 | else ite.Next(); |
1006 | } |
1007 | } |
1008 | } |
1009 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE3 ); |
1010 | } |
1011 | else index++; |
1012 | } |
1013 | else |
1014 | { |
1015 | //gka protection aginst removing circles |
1016 | TopoDS_Edge ed = (take_next ? edge1 : edge2); |
1017 | ShapeAnalysis_Edge sae; |
1018 | Handle(Geom_Curve) c3d; |
1019 | Standard_Real f1,l1; |
1020 | if(sae.Curve3d(ed,c3d,f1,l1,Standard_False)) |
1021 | { |
1022 | gp_Pnt p1,p2,p3; |
1023 | c3d->D0(f1,p1); |
1024 | c3d->D0(l1,p2); |
1025 | c3d->D0((f1 +l1)*0.5,p3); |
1026 | |
1027 | if(p1.Distance(p3) > p1.Distance(p2)) |
1028 | { |
1029 | index++; |
1030 | continue; |
1031 | } |
1032 | } |
1033 | if (take_next && theList2.Extent()== 1) |
1034 | { //gka |
1035 | TopoDS_Vertex V1 = SAE.FirstVertex(edge1), |
1036 | V2 = SAE.LastVertex(edge1); |
1037 | if(V1.IsSame(V2)) |
1038 | { |
1039 | SFW->WireData()->Remove (index ); |
1040 | Context()->Remove(edge1); |
1041 | if (theSmallEdges.Contains(edge1)) theSmallEdges.Remove(edge1); |
1042 | theEdgeToFaces.UnBind(edge1); |
1043 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1044 | } |
1045 | else index++; |
1046 | } |
1047 | else if( !take_next && theList2.Extent()== 1) |
1048 | { |
1049 | TopoDS_Vertex V1 = SAE.FirstVertex(edge2), |
1050 | V2 = SAE.LastVertex(edge2); |
1051 | if(V1.IsSame(V2)) |
1052 | { |
1053 | SFW->WireData()->Remove (index ); |
1054 | Context()->Remove(edge2); |
1055 | if (theSmallEdges.Contains(edge2)) theSmallEdges.Remove(edge2); |
1056 | theEdgeToFaces.UnBind(edge2); |
1057 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1058 | } |
1059 | else index++; |
1060 | } |
1061 | else index++; |
1062 | } |
1063 | } |
1064 | else index++; |
1065 | } |
1066 | if (SFW->NbEdges() == 1 && aModeDrop) |
1067 | { |
1068 | edge1 = SFW->WireData()->Edge(1); |
1069 | if (theSmallEdges.Contains(edge1)) |
1070 | { |
1071 | SFW->WireData()->Remove(1); |
1072 | Context()->Remove(edge1); |
1073 | theSmallEdges.Remove(edge1); |
1074 | theEdgeToFaces.UnBind(edge1); |
1075 | Context()->Remove(aWire); |
1076 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1077 | } |
1078 | } |
1079 | else |
1080 | { |
1081 | SFW->FixConnected(); |
1082 | Context()->Replace(aWire,SFW->Wire()); |
1083 | } |
1084 | } |
1085 | face.Orientation(facet.Orientation()); |
1086 | TopoDS_Shape anewShape = Context()->Apply(face); |
1087 | TopoDS_Iterator aIter(anewShape); |
1088 | if(!aIter.More()) |
1089 | Context()->Remove(anewShape); |
1090 | } |
1091 | } |
1092 | } |
1093 | |
1094 | // enk block |
1095 | // Iterate on map of wires which not lie on faces |
1096 | for (TopExp_Explorer expw1( myShape, TopAbs_WIRE, TopAbs_FACE); expw1.More(); expw1.Next()) |
1097 | { |
1098 | TopoDS_Wire aWire = TopoDS::Wire(expw1.Current()); |
1099 | SFW->Load(aWire); |
1100 | SFW->FixReorder(); |
1101 | Standard_Integer prev, next, index = 1; |
1102 | while (index <= SFW->NbEdges() && SFW->NbEdges()>1) |
1103 | { |
1104 | prev = (index==1)? SFW->NbEdges() : index-1; |
1105 | next = (index==SFW->NbEdges())? 1 : index+1; |
1106 | edge1 = SFW->WireData()->Edge(prev); |
1107 | edge2 = SFW->WireData()->Edge(index); |
1108 | edge3 = SFW->WireData()->Edge(next); |
1109 | |
1110 | //gka protection against joining seem edge |
1111 | if(edge2.IsSame(edge1) || edge2.IsSame(edge3)) |
1112 | { |
1113 | //if(BRep_Tool::IsClosed(edge2,face)) { |
1114 | index++; |
1115 | continue; |
1116 | } |
1117 | |
1118 | Standard_Boolean isSeam = SFW->WireData()->IsSeam(index); |
1119 | Standard_Boolean isSeam1 = SFW->WireData()->IsSeam(prev); |
1120 | Standard_Boolean isSeam2 = SFW->WireData()->IsSeam(next); |
1121 | if (theSmallEdges.Contains(edge2)) |
1122 | { |
1123 | // Middle edge is small - choose a pair of edges to join |
1124 | Standard_Boolean IsAnyJoin = (edge1.IsSame(edge3)); |
1125 | Standard_Boolean take_next = IsAnyJoin; //Standard_False; |
1126 | Standard_Boolean isLimAngle = Standard_False; |
1127 | Handle(Geom_Curve) C1, C2, C3; |
1128 | Standard_Real aux, last1, first2, last2, first3; |
1129 | Standard_Real Ang1 = 0., Ang2 =0.; |
1130 | if (SAE.Curve3d(edge1,C1,aux,last1) && |
1131 | SAE.Curve3d(edge2,C2,first2,last2) && |
1132 | SAE.Curve3d(edge3,C3,first3,aux)) |
1133 | { |
1134 | // Compare angles between edges |
1135 | //Standard_Real Ang1, Ang2; |
1136 | gp_Vec Vec1, Vec2; gp_Pnt P; |
1137 | C1->D1(last1,P,Vec1); |
1138 | C2->D1(first2,P,Vec2); |
1139 | if ( edge1.Orientation() == TopAbs_REVERSED ) Vec1.Reverse(); |
1140 | if ( edge2.Orientation() == TopAbs_REVERSED ) Vec2.Reverse(); |
08cd2f6b |
1141 | Standard_Real tol2 = Precision::SquareConfusion(); |
7fd59977 |
1142 | if ( Vec1.SquareMagnitude() < tol2 || |
c6541a0c |
1143 | Vec2.SquareMagnitude() < tol2 ) Ang1 = M_PI/2.; |
7fd59977 |
1144 | else Ang1 = Abs(Vec1.Angle(Vec2)); |
1145 | C2->D1(last2,P,Vec1); |
1146 | C3->D1(first3,P,Vec2); |
1147 | if ( edge2.Orientation() == TopAbs_REVERSED ) Vec1.Reverse(); |
1148 | if ( edge3.Orientation() == TopAbs_REVERSED ) Vec2.Reverse(); |
1149 | if ( Vec1.SquareMagnitude() < tol2 || |
c6541a0c |
1150 | Vec2.SquareMagnitude() < tol2 ) Ang2 = M_PI/2.; |
7fd59977 |
1151 | else Ang2 = Abs(Vec1.Angle(Vec2)); |
1152 | //isLimAngle = (theLimitAngle != -1 && Min(Ang1,Ang2) > theLimitAngle); |
1153 | //take_next = (Ang2<Ang1); |
1154 | //if (take_next) { edge1 = edge2; edge2 = edge3; } |
1155 | } |
1156 | //if(theLimitAngle != -1 && Ang1 > theLimitAngle && Ang2 >theLimitAngle) { |
1157 | // index++; continue; |
1158 | //} |
1159 | |
1160 | // Check if edges lay on the same faces |
1161 | if(theMultyEdges.Contains(edge1) || theMultyEdges.Contains(edge2)) |
1162 | { //?????? |
1163 | index++; |
1164 | continue; |
1165 | } |
1166 | TopTools_ListOfShape theList1,theList2,theList3; |
1167 | if(theEdgeToFaces.IsBound(edge1)) |
1168 | theList1 = theEdgeToFaces(edge1); |
1169 | if(theEdgeToFaces.IsBound(edge2)) |
1170 | theList2 = theEdgeToFaces(edge2); |
1171 | if(theEdgeToFaces.IsBound(edge3)) |
1172 | theList3 = theEdgeToFaces(edge3); |
1173 | Standard_Boolean same_set = Standard_False; |
1174 | |
1175 | //gka protection against joining seem edges with other edges |
1176 | Standard_Boolean same_set1 = (theList1.Extent()==theList2.Extent() && |
1177 | ((!isSeam && !isSeam1)|| (isSeam && isSeam1))); //gka |
1178 | Standard_Boolean same_set2 = (theList3.Extent()==theList2.Extent() && |
1179 | ((!isSeam && !isSeam2)|| (isSeam && isSeam2))); |
1180 | TopTools_MapOfShape theSetOfFaces; |
1181 | for (TopTools_ListIteratorOfListOfShape itf1(theList2); |
1182 | itf1.More(); itf1.Next()) |
1183 | theSetOfFaces.Add(itf1.Value()); |
1184 | if (same_set1) |
1185 | { |
1186 | // Add all faces of the first edge to the current set |
1187 | for (TopTools_ListIteratorOfListOfShape itf2(theList1); |
1188 | (itf2.More() && same_set1); itf2.Next()) |
1189 | same_set1 = theSetOfFaces.Contains(itf2.Value()); |
1190 | } |
1191 | if (same_set2) |
1192 | { |
1193 | // Add all faces of the first edge to the current set |
1194 | for (TopTools_ListIteratorOfListOfShape itf2(theList3); |
1195 | (itf2.More() && same_set2); itf2.Next()) |
1196 | same_set2 = theSetOfFaces.Contains(itf2.Value()); |
1197 | } |
1198 | if(same_set1 && same_set2) |
1199 | { |
1200 | same_set = Standard_True; |
1201 | if(fabs(Ang2-Ang1) >Precision::Angular()) |
1202 | take_next = (Ang2<Ang1); |
1203 | if (take_next) |
1204 | { |
1205 | edge1 = edge2; edge2 = edge3; |
1206 | } |
1207 | isLimAngle = (aModLimitAngle && Min(Ang1,Ang2) > aLimitAngle); |
1208 | } |
1209 | else if(same_set1 && !same_set2) |
1210 | { |
1211 | isLimAngle = (aModLimitAngle && Ang1 > aLimitAngle); |
1212 | same_set = Standard_True; |
1213 | } |
1214 | else if(!same_set1 && same_set2) |
1215 | { |
1216 | same_set = Standard_True; |
1217 | isLimAngle = (aModLimitAngle && Ang2 > aLimitAngle); |
1218 | edge1 = edge2; edge2 = edge3; |
1219 | take_next = Standard_True; |
1220 | } |
1221 | if (same_set && !isLimAngle ) |
1222 | { |
1223 | // Merge current pair of edges |
1224 | //gka protection against crossing seem on second face |
1225 | Standard_Boolean isNeedJoin = Standard_True;//Standard_False; |
1226 | for(TopTools_ListIteratorOfListOfShape aItF(theList2); aItF.More() && isNeedJoin; aItF.Next()) |
1227 | { |
1228 | if(aItF.Value().IsSame(anExpf2.Current())) continue; |
1229 | TopoDS_Shape aF = Context()->Apply(aItF.Value()); |
1230 | //aF = aF.Oriented(TopAbs_FORWARD); |
1231 | for(TopoDS_Iterator aIw(aF); aIw.More(); aIw.Next()) |
1232 | { |
1233 | if(aIw.Value().ShapeType() != TopAbs_WIRE) continue; |
1234 | TopoDS_Wire wt = TopoDS::Wire(aIw.Value()); |
1235 | Handle(ShapeFix_Wire) SFW1 = new ShapeFix_Wire; |
1236 | SFW1->Load(wt); |
1237 | SFW1->FixReorder(); |
1238 | Handle(ShapeExtend_WireData) atmpswd = SFW1->WireData(); |
1239 | Standard_Integer ind1 = atmpswd->Index(edge1); |
1240 | Standard_Integer ind2 = atmpswd->Index(edge2); |
1241 | if(ind1 && ind2) |
1242 | { |
1243 | isNeedJoin = ((ind1 -ind2) ==1 || (ind2 == atmpswd->NbEdges() && ind1 ==1)); |
1244 | break; |
1245 | } |
1246 | } |
1247 | } |
1248 | Standard_Boolean ReplaceFirst = Standard_True; |
1249 | if(isNeedJoin) |
1250 | { |
1251 | |
1252 | TopTools_ListOfShape aListF; |
1253 | for(TopTools_ListIteratorOfListOfShape aItlF(theList2); aItlF.More(); aItlF.Next()) |
1254 | { |
1255 | TopoDS_Shape tmpF = Context()->Apply(aItlF.Value()); |
1256 | aListF.Append(tmpF); |
1257 | } |
1258 | ReplaceFirst = JoinEdges(edge1,edge2,edge3,aListF); |
1259 | } |
1260 | else edge3 = TopoDS_Edge(); |
1261 | if (edge3.IsNull()) |
1262 | { |
1263 | index++; |
1264 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_FAIL1 ); |
1265 | } |
1266 | else |
1267 | { |
1268 | // Record vertex replacements in the map |
1269 | TopoDS_Vertex oldV1 = SAE.FirstVertex(edge3), |
1270 | oldV2 = SAE.LastVertex(edge3); |
1271 | if (!theNewVertices.IsBound(oldV1)) |
1272 | //smh#8 |
1273 | { |
1274 | TopoDS_Shape emptyCopiedV1 = oldV1.EmptyCopied(); |
1275 | theNewVertices.Bind(oldV1,TopoDS::Vertex(emptyCopiedV1)); |
1276 | } |
1277 | if (!oldV1.IsSame(oldV2)) |
1278 | if (!theNewVertices.IsBound(oldV2)) |
1279 | //smh#8 |
1280 | { |
1281 | TopoDS_Shape emptyCopiedV2 = oldV2.EmptyCopied(); |
1282 | theNewVertices.Bind(oldV2,TopoDS::Vertex(emptyCopiedV2)); |
1283 | } |
1284 | //To keep NM vertices belonging initial edges |
1285 | TopoDS_Iterator aItv(edge1,Standard_False); |
1286 | for( ; aItv.More(); aItv.Next()) { |
1287 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
1288 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
1289 | BRep_Builder aB; |
1290 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
1291 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,edge3,edge1); |
1292 | aB.Add(edge3,anewV); |
1293 | Context()->Replace(aOldV,anewV); |
1294 | } |
1295 | } |
1296 | |
1297 | for(aItv.Initialize(edge2,Standard_False) ; aItv.More(); aItv.Next()) { |
1298 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
1299 | aItv.Value().Orientation() == TopAbs_EXTERNAL){ |
1300 | BRep_Builder aB; |
1301 | TopoDS_Vertex aOldV = TopoDS::Vertex(aItv.Value()); |
1302 | TopoDS_Vertex anewV = ShapeAnalysis_TransferParametersProj::CopyNMVertex(aOldV,edge3,edge2); |
1303 | aB.Add(edge3,anewV); |
1304 | Context()->Replace(aOldV,anewV); |
1305 | } |
1306 | } |
1307 | // Check for small resulting edge |
1308 | Standard_Boolean newsmall = Standard_False; |
1309 | ShapeAnalysis_Wire SAW; |
1310 | SAW.Load(SFW->WireData()); |
1311 | SAW.SetPrecision(Precision()); |
1312 | // Make changes in WireData and Context |
1313 | if(ReplaceFirst) |
1314 | { |
1315 | Context()->Replace(edge1,edge3); |
1316 | Context()->Remove(edge2); |
1317 | } |
1318 | else |
1319 | { |
1320 | Context()->Replace(edge2,edge3); |
1321 | Context()->Remove(edge1); |
1322 | } |
1323 | if (take_next) |
1324 | { |
1325 | SFW->WireData()->Set(edge3,next); |
1326 | newsmall = SAW.CheckSmall(next,Precision()); |
1327 | } |
1328 | else |
1329 | { |
1330 | SFW->WireData()->Set(edge3,prev); |
1331 | newsmall = SAW.CheckSmall(prev,Precision()); |
1332 | } |
1333 | SFW->WireData()->Remove(index); |
1334 | // Process changes in maps |
1335 | TopTools_ListOfShape theList; |
1336 | theList.Append(theList2); |
1337 | theEdgeToFaces.UnBind(edge1); |
1338 | theEdgeToFaces.UnBind(edge2); |
1339 | theEdgeToFaces.Bind(edge3,theList); |
1340 | if (theSmallEdges.Contains(edge1)) theSmallEdges.Remove(edge1); |
1341 | if (theSmallEdges.Contains(edge2)) theSmallEdges.Remove(edge2); |
1342 | if (newsmall) theSmallEdges.Add(edge3); |
1343 | for (TopTools_ListIteratorOfListOfShape itlf(theList); |
1344 | itlf.More(); itlf.Next()) |
1345 | { |
1346 | TopoDS_Shape curface = itlf.Value(); |
1347 | if (theFaceWithSmall.IsBound(curface)) |
1348 | { |
1349 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
1350 | if (newsmall) theEdges.Append(edge3); |
1351 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
1352 | while (ite.More()) |
1353 | { |
1354 | TopoDS_Shape iedge = ite.Value(); |
1355 | if (iedge.IsSame(edge1) || iedge.IsSame(edge2)) |
1356 | theEdges.Remove(ite); |
1357 | else ite.Next(); |
1358 | } |
1359 | // Remove face without small edges from the map |
1360 | if (!theEdges.Extent()) theFaceWithSmall.UnBind(curface); |
1361 | } |
1362 | } |
1363 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE1 ); |
1364 | } |
1365 | } |
1366 | else if(aModeDrop) |
1367 | { //gka |
1368 | Handle(ShapeExtend_WireData) tempWire = new ShapeExtend_WireData(); |
1369 | ShapeAnalysis_Wire tempSaw; |
1370 | tempWire->Add(SFW->Wire()); |
1371 | TopoDS_Edge remedge; |
1372 | if (take_next) |
1373 | remedge = edge1; |
1374 | else remedge = edge2; |
1375 | tempWire->Remove (index ); |
1376 | tempSaw.Load(tempWire); |
1377 | Standard_Integer newindex = (index <= tempSaw.NbEdges() ? index : 1); |
1378 | tempSaw.CheckConnected(newindex,Precision()); |
1379 | if(!tempSaw.LastCheckStatus(ShapeExtend_FAIL)) |
1380 | { |
1381 | SFW->WireData()->Remove (index ); |
1382 | TopoDS_Edge tmpedge1 = tempWire->Edge(newindex); |
1383 | TopoDS_Edge tmpedge2 = tempWire->Edge(newindex == 1 ? tempSaw.NbEdges() : (newindex- 1)); |
1384 | TopTools_ListOfShape aL1; |
1385 | if(theEdgeToFaces.IsBound(tmpedge1)) |
1386 | aL1 = theEdgeToFaces.Find(tmpedge1); |
1387 | TopTools_ListOfShape aL2; |
1388 | if(theEdgeToFaces.IsBound(tmpedge2)) |
1389 | aL2= theEdgeToFaces.Find(tmpedge2); |
1390 | SFW->FixConnected(newindex <= SFW->NbEdges() ? newindex : 1,Precision()); |
1391 | SFW->FixDegenerated(newindex <= SFW->NbEdges() ? newindex : 1); |
1392 | TopoDS_Shape aTmpShape = Context()->Apply(tmpedge1); //for porting |
1393 | TopoDS_Edge anewedge1 = TopoDS::Edge(aTmpShape); |
1394 | aTmpShape = Context()->Apply(tmpedge2); |
1395 | TopoDS_Edge anewedge2 = TopoDS::Edge(aTmpShape); |
1396 | Context()->Remove(remedge); |
1397 | if (theSmallEdges.Contains(remedge)) |
1398 | theSmallEdges.Remove(remedge); |
1399 | theEdgeToFaces.UnBind(remedge); |
1400 | theEdgeToFaces.UnBind(tmpedge1); |
1401 | theEdgeToFaces.UnBind(tmpedge2); |
1402 | theEdgeToFaces.Bind(anewedge1,aL1); |
1403 | theEdgeToFaces.Bind(anewedge2,aL2); |
1404 | if (theSmallEdges.Contains(tmpedge1)) |
1405 | { |
1406 | theSmallEdges.Remove(tmpedge1); |
1407 | theSmallEdges.Add(anewedge1); |
1408 | for (TopTools_ListIteratorOfListOfShape itlf(aL1); |
1409 | itlf.More(); itlf.Next()) |
1410 | { |
1411 | TopoDS_Shape curface = itlf.Value(); |
1412 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
1413 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
1414 | while (ite.More()) |
1415 | { |
1416 | TopoDS_Shape iedge = ite.Value(); |
1417 | if (iedge.IsSame(tmpedge1)) |
1418 | { |
1419 | theEdges.Remove(ite); |
1420 | theEdges.Append(anewedge1); |
1421 | } |
1422 | else ite.Next(); |
1423 | } |
1424 | } |
1425 | } |
1426 | if (theSmallEdges.Contains(tmpedge2)) |
1427 | { |
1428 | theSmallEdges.Remove(tmpedge2); |
1429 | theSmallEdges.Add(anewedge2); |
1430 | for (TopTools_ListIteratorOfListOfShape itlf(aL2); |
1431 | itlf.More(); itlf.Next()) |
1432 | { |
1433 | TopoDS_Shape curface = itlf.Value(); |
1434 | TopTools_ListOfShape& theEdges = theFaceWithSmall(curface); |
1435 | TopTools_ListIteratorOfListOfShape ite(theEdges); |
1436 | while (ite.More()) |
1437 | { |
1438 | TopoDS_Shape iedge = ite.Value(); |
1439 | if (iedge.IsSame(tmpedge2)) |
1440 | { |
1441 | theEdges.Remove(ite); |
1442 | theEdges.Append(anewedge2); |
1443 | } |
1444 | else ite.Next(); |
1445 | } |
1446 | } |
1447 | } |
1448 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE3 ); |
1449 | } |
1450 | else index++; |
1451 | } |
1452 | else |
1453 | { |
1454 | //gka protection aginst removing circles |
1455 | TopoDS_Edge ed = (take_next ? edge1 : edge2); |
1456 | ShapeAnalysis_Edge sae; |
1457 | Handle(Geom_Curve) c3d; |
1458 | Standard_Real f1,l1; |
1459 | if(sae.Curve3d(ed,c3d,f1,l1,Standard_False)) |
1460 | { |
1461 | gp_Pnt p1,p2,p3; |
1462 | c3d->D0(f1,p1); |
1463 | c3d->D0(l1,p2); |
1464 | c3d->D0((f1 +l1)*0.5,p3); |
1465 | |
1466 | if(p1.Distance(p3) > p1.Distance(p2)) |
1467 | { |
1468 | index++; |
1469 | continue; |
1470 | } |
1471 | } |
1472 | if (take_next && theList2.Extent()== 1) |
1473 | { //gka |
1474 | TopoDS_Vertex V1 = SAE.FirstVertex(edge1), |
1475 | V2 = SAE.LastVertex(edge1); |
1476 | if(V1.IsSame(V2)) |
1477 | { |
1478 | SFW->WireData()->Remove (index ); |
1479 | Context()->Remove(edge1); |
1480 | if (theSmallEdges.Contains(edge1)) theSmallEdges.Remove(edge1); |
1481 | theEdgeToFaces.UnBind(edge1); |
1482 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1483 | } |
1484 | else index++; |
1485 | } |
1486 | else if( !take_next && theList2.Extent()== 1) |
1487 | { |
1488 | TopoDS_Vertex V1 = SAE.FirstVertex(edge2), |
1489 | V2 = SAE.LastVertex(edge2); |
1490 | if(V1.IsSame(V2)) |
1491 | { |
1492 | SFW->WireData()->Remove (index ); |
1493 | Context()->Remove(edge2); |
1494 | if (theSmallEdges.Contains(edge2)) theSmallEdges.Remove(edge2); |
1495 | theEdgeToFaces.UnBind(edge2); |
1496 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1497 | } |
1498 | else index++; |
1499 | } |
1500 | else index++; |
1501 | } |
1502 | } |
1503 | else index++; |
1504 | } |
1505 | if (SFW->NbEdges() == 1 && aModeDrop) |
1506 | { |
1507 | edge1 = SFW->WireData()->Edge(1); |
1508 | if (theSmallEdges.Contains(edge1)) |
1509 | { |
1510 | SFW->WireData()->Remove(1); |
1511 | Context()->Remove(edge1); |
1512 | theSmallEdges.Remove(edge1); |
1513 | theEdgeToFaces.UnBind(edge1); |
1514 | Context()->Remove(aWire); |
1515 | myStatusSmallEdges |= ShapeExtend::EncodeStatus( ShapeExtend_DONE2 ); |
1516 | } |
1517 | } |
1518 | else |
1519 | { |
1520 | SFW->FixConnected(); |
1521 | Context()->Replace(aWire,SFW->Wire()); |
1522 | } |
1523 | } |
1524 | // end enk block |
1525 | // Record vertex replacements in context |
1526 | for (TopTools_DataMapIteratorOfDataMapOfShapeShape itv(theNewVertices); |
1527 | itv.More(); itv.Next()) Context()->Replace(itv.Key(),itv.Value()); |
1528 | |
1529 | TopoDS_Shape shape = myShape; |
1530 | myShape.Nullify(); |
1531 | myShape = Context()->Apply(shape); |
1532 | |
1533 | ShapeFix::SameParameter(myShape,Standard_False); |
1534 | |
1535 | return StatusSmallEdges( ShapeExtend_DONE ); |
1536 | } |
1537 | |
1538 | return Standard_False; |
1539 | } |