7fd59977 |
1 | // File: BRepOffsetAPI_DraftAngle.cxx |
2 | // Created: Wed Feb 22 11:32:25 1995 |
3 | // Author: Jacques GOUSSARD |
4 | // <jag@topsn2> |
5 | |
6 | |
7 | #include <BRepOffsetAPI_DraftAngle.ixx> |
8 | |
9 | #include <Draft_Modification.hxx> |
10 | #include <TopoDS.hxx> |
11 | #include <Geom_Surface.hxx> |
12 | #include <TopLoc_Location.hxx> |
13 | |
14 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
15 | |
16 | #include <BRepLib.hxx> |
17 | #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx> |
18 | #include <TopTools_DataMapOfShapeSequenceOfShape.hxx> |
19 | #include <TopTools_SequenceOfShape.hxx> |
20 | #include <TopoDS_Iterator.hxx> |
21 | #include <TopExp_Explorer.hxx> |
22 | #include <BRepTools.hxx> |
23 | #include <TColgp_SequenceOfPnt.hxx> |
24 | #include <TColStd_SequenceOfReal.hxx> |
25 | #include <TopOpeBRep_EdgesIntersector.hxx> |
26 | #include <TopOpeBRep_Point2d.hxx> |
27 | #include <Precision.hxx> |
28 | #include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx> |
29 | #include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx> |
30 | #include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx> |
31 | #include <BRepTools_Substitution.hxx> |
32 | #include <BRep_Builder.hxx> |
33 | #include <TopExp.hxx> |
34 | #include <BRep_Tool.hxx> |
35 | #include <BRepAdaptor_Curve.hxx> |
36 | #include <BRepLib_MakeVertex.hxx> |
37 | #include <BRep_TEdge.hxx> |
38 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
39 | #include <BRep_GCurve.hxx> |
40 | #include <TopoDS_Wire.hxx> |
41 | #include <BRepAdaptor_Curve2d.hxx> |
42 | |
43 | //======================================================================= |
44 | //function : BRepOffsetAPI_DraftAngle |
45 | //purpose : |
46 | //======================================================================= |
47 | |
48 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {} |
49 | |
50 | |
51 | //======================================================================= |
52 | //function : BRepOffsetAPI_DraftAngle |
53 | //purpose : |
54 | //======================================================================= |
55 | |
56 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S) |
57 | { |
58 | myInitialShape = S; |
59 | myModification = new Draft_Modification(S); |
60 | } |
61 | |
62 | |
63 | //======================================================================= |
64 | //function : Clear |
65 | //purpose : |
66 | //======================================================================= |
67 | |
68 | void BRepOffsetAPI_DraftAngle::Clear () |
69 | { |
70 | if (!myModification.IsNull()) { |
71 | (*((Handle(Draft_Modification)*)&myModification))->Clear(); |
72 | } |
73 | } |
74 | |
75 | |
76 | //======================================================================= |
77 | //function : Init |
78 | //purpose : |
79 | //======================================================================= |
80 | |
81 | void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S) |
82 | { |
83 | myInitialShape = S; |
84 | NotDone(); |
85 | if (!myModification.IsNull()) { |
86 | (*((Handle(Draft_Modification)*)&myModification))->Init(S); |
87 | } |
88 | else { |
89 | myModification = new Draft_Modification(S); |
90 | } |
91 | } |
92 | |
93 | |
94 | //======================================================================= |
95 | //function : Add |
96 | //purpose : |
97 | //======================================================================= |
98 | |
99 | void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F, |
100 | const gp_Dir& D, |
101 | const Standard_Real Angle, |
102 | const gp_Pln& Plane, |
103 | const Standard_Boolean Flag) |
104 | { |
105 | // POP-DPF : protection |
106 | if ( Abs(Angle) <= 1.e-04 ) |
107 | return; |
108 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
109 | (*((Handle(Draft_Modification)*)&myModification))->Add(F,D,Angle,Plane, Flag); |
110 | } |
111 | |
112 | |
113 | //======================================================================= |
114 | //function : AddDone |
115 | //purpose : |
116 | //======================================================================= |
117 | |
118 | Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const |
119 | { |
120 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
121 | return (*((Handle(Draft_Modification)*)&myModification)) |
122 | ->ProblematicShape().IsNull(); |
123 | } |
124 | |
125 | |
126 | //======================================================================= |
127 | //function : Remove |
128 | //purpose : |
129 | //======================================================================= |
130 | |
131 | void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F) |
132 | { |
133 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
134 | (*((Handle(Draft_Modification)*)&myModification))->Remove(F); |
135 | } |
136 | |
137 | |
138 | //======================================================================= |
139 | //function : ProblematicShape |
140 | //purpose : |
141 | //======================================================================= |
142 | |
143 | const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const |
144 | { |
145 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
146 | return (*((Handle(Draft_Modification)*)&myModification))->ProblematicShape(); |
147 | } |
148 | |
149 | |
150 | //======================================================================= |
151 | //function : ErrorStatus |
152 | //purpose : |
153 | //======================================================================= |
154 | |
155 | Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const |
156 | { |
157 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
158 | return (*((Handle(Draft_Modification)*)&myModification))->Error(); |
159 | } |
160 | |
161 | |
162 | //======================================================================= |
163 | //function : ConnectedFaces |
164 | //purpose : |
165 | //======================================================================= |
166 | |
167 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces |
168 | (const TopoDS_Face& F) const |
169 | { |
170 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
171 | return (*((Handle(Draft_Modification)*)&myModification))->ConnectedFaces(F); |
172 | } |
173 | |
174 | |
175 | //======================================================================= |
176 | //function : ModifiedFaces |
177 | //purpose : |
178 | //======================================================================= |
179 | |
180 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const |
181 | { |
182 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
183 | return (*((Handle(Draft_Modification)*)&myModification))->ModifiedFaces(); |
184 | } |
185 | |
186 | //======================================================================= |
187 | //function : ModifiedFaces |
188 | //purpose : |
189 | //======================================================================= |
190 | |
191 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S) |
192 | { |
193 | myGenerated.Clear(); |
194 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
195 | Handle(Draft_Modification) DMod = (*((Handle(Draft_Modification)*)&myModification)); |
196 | |
197 | if (S.ShapeType() == TopAbs_FACE) { |
198 | Handle(Geom_Surface) Surf; |
199 | TopLoc_Location L; |
200 | Standard_Real Tol; |
201 | Standard_Boolean RW,RF; |
202 | if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
203 | myGenerated.Append(ModifiedShape (S)); |
204 | |
205 | } |
206 | } |
207 | return myGenerated; |
208 | } |
209 | |
210 | //======================================================================= |
211 | //function : ModifiedFaces |
212 | //purpose : |
213 | //======================================================================= |
214 | |
215 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) |
216 | { |
217 | myGenerated.Clear(); |
218 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
219 | Handle(Draft_Modification) DMod = (*((Handle(Draft_Modification)*)&myModification)); |
220 | |
221 | if (S.ShapeType() == TopAbs_FACE) { |
222 | Handle(Geom_Surface) Surf; |
223 | TopLoc_Location L; |
224 | Standard_Real Tol; |
225 | Standard_Boolean RW,RF; |
226 | |
227 | if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
228 | // Ce n est pas une generation => peut etre une modif |
229 | myGenerated.Append(ModifiedShape (S)); |
230 | if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) { |
231 | myGenerated.Clear(); |
232 | } |
233 | } |
234 | } |
235 | return myGenerated; |
236 | } |
237 | |
238 | |
239 | //======================================================================= |
240 | //function : Build |
241 | //purpose : |
242 | //======================================================================= |
243 | |
244 | void BRepOffsetAPI_DraftAngle::Build() |
245 | { |
246 | (*((Handle(Draft_Modification)*)&myModification))->Perform(); |
247 | if (!(*((Handle(Draft_Modification)*)&myModification))->IsDone()) { |
248 | NotDone(); |
249 | } |
250 | else { |
251 | DoModif(myInitialShape); |
252 | //BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch |
253 | CorrectWires(); |
254 | BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch |
255 | } |
256 | } |
257 | |
258 | //======================================================================= |
259 | //function : CorrectWires |
260 | //purpose : |
261 | //======================================================================= |
262 | |
263 | void BRepOffsetAPI_DraftAngle::CorrectWires() |
264 | { |
265 | Standard_Real TolInter = 1.e-7; |
266 | Standard_Integer i, j, k; |
267 | |
268 | TopTools_SequenceOfShape Eseq; |
269 | TopTools_SequenceOfShape Wseq; |
270 | TopTools_SequenceOfShape Fseq; |
271 | TopoDS_Shape CurEdge, CurWire, CurFace; |
272 | TopoDS_Iterator wit, eit; |
273 | |
274 | TopExp_Explorer fexp( myShape, TopAbs_FACE ); |
275 | for (; fexp.More(); fexp.Next()) |
276 | { |
277 | CurFace = fexp.Current(); |
278 | wit.Initialize( CurFace ); |
279 | for (; wit.More(); wit.Next()) |
280 | { |
281 | CurWire = wit.Value(); |
282 | TopTools_MapOfShape emap; |
283 | eit.Initialize( CurWire ); |
284 | for (; eit.More(); eit.Next()) |
285 | emap.Add( eit.Value() ); |
286 | TopTools_MapIteratorOfMapOfShape mapit( emap ); |
287 | for (; mapit.More(); mapit.Next()) |
288 | { |
289 | CurEdge = mapit.Key(); |
290 | if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) )) |
291 | { |
292 | Eseq.Append( CurEdge ); |
293 | Wseq.Append( CurWire ); |
294 | Fseq.Append( CurFace ); |
295 | } |
296 | } |
297 | } |
298 | } |
299 | |
300 | BRepFill_DataMapOfShapeSequenceOfReal Emap; |
301 | |
302 | TopTools_SequenceOfShape NonSeam; |
303 | TopTools_SequenceOfShape NonSeamWires; |
304 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam; |
305 | BRepOffsetAPI_SequenceOfSequenceOfShape Seam; |
306 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam; |
307 | |
308 | TopTools_DataMapOfShapeShape WFmap; |
309 | TopTools_DataMapOfShapeListOfShape WWmap; |
310 | for (i = 1; i <= Eseq.Length(); i++) |
311 | { |
312 | CurEdge = Eseq(i); |
313 | CurWire = Wseq(i); |
314 | CurFace = Fseq(i); |
315 | wit.Initialize( CurFace ); |
316 | for (; wit.More(); wit.Next()) |
317 | { |
318 | TopoDS_Shape aWire = wit.Value(); |
319 | if (! aWire.IsSame( CurWire )) |
320 | { |
321 | TColgp_SequenceOfPnt pts; |
322 | TopTools_SequenceOfShape edges; |
323 | TColStd_SequenceOfReal pars; |
324 | Standard_Boolean Wadd = Standard_False; |
325 | eit.Initialize( aWire ); |
326 | for (; eit.More(); eit.Next()) |
327 | { |
328 | TopoDS_Shape anEdge = eit.Value(); |
329 | TopOpeBRep_EdgesIntersector EInter; |
330 | EInter.SetFaces( CurFace, CurFace ); |
331 | EInter.ForceTolerances( TolInter, TolInter ); |
332 | EInter.Perform( CurEdge, anEdge ); |
333 | if (EInter.IsEmpty()) |
334 | { |
335 | EInter.Perform( CurEdge.Reversed(), anEdge ); |
336 | if (EInter.IsEmpty()) |
337 | continue; |
338 | } |
339 | Wadd = Standard_True; |
340 | if (! WFmap.IsBound( aWire )) |
341 | WFmap.Bind( aWire, CurFace ); |
342 | Standard_Integer ind = 0; |
343 | for (j = 1; j <= NonSeam.Length(); j++) |
344 | if (anEdge.IsSame( NonSeam(j) )) |
345 | { |
346 | ind = j; |
347 | break; |
348 | } |
349 | if (ind == 0) |
350 | { |
351 | NonSeam.Append( anEdge ); |
352 | NonSeamWires.Append( aWire ); |
353 | ind = NonSeam.Length(); |
354 | TColStd_SequenceOfReal emptyseq1, emptyseq2; |
355 | TopTools_SequenceOfShape emptyedgeseq; |
356 | ParsNonSeam.Append( emptyseq1 ); |
357 | Seam.Append( emptyedgeseq ); |
358 | ParsSeam.Append( emptyseq2 ); |
359 | } |
360 | if (! Emap.IsBound( CurEdge )) |
361 | { |
362 | TColStd_SequenceOfReal emptyseq; |
363 | Emap.Bind( CurEdge, emptyseq ); |
364 | } |
365 | EInter.InitPoint(); |
366 | for (; EInter.MorePoint(); EInter.NextPoint()) |
367 | { |
368 | const TopOpeBRep_Point2d& bp = EInter.Point(); |
369 | if (bp.IsVertex(2)) |
370 | { |
371 | gp_Pnt Pnt = bp.Value(); |
372 | Standard_Integer ied = 0; |
373 | for (j = 1; j <= pts.Length(); j++) |
374 | if (Pnt.IsEqual( pts(j), Precision::Confusion() )) |
375 | { |
376 | ied = j; |
377 | break; |
378 | } |
379 | if (ied == 0) |
380 | { |
381 | pts.Append( Pnt ); |
382 | edges.Append( anEdge ); |
383 | pars.Append( bp.Parameter(2) ); |
384 | Emap(CurEdge).Append( bp.Parameter(1) ); |
385 | ParsNonSeam(ind).Append( bp.Parameter(2) ); |
386 | Seam(ind).Append( CurEdge ); |
387 | ParsSeam(ind).Append( bp.Parameter(1) ); |
388 | } |
389 | /* |
390 | else |
391 | { |
392 | Standard_Real ParOnSeam = bp.Parameter(1); |
393 | Standard_Real Par1 = pars(ied); |
394 | Standard_Real Par2 = bp.Parameter(2); |
395 | BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace ); |
396 | BRepAdaptor_Curve2d Curve1( edges(ied), CurFace ); |
397 | BRepAdaptor_Curve2d Curve2( anEdge. CurFace ); |
398 | gp_Pnt2d P2d; |
399 | gp_Vec2d SeamDer, Der1, Der2; |
400 | //SeamCurve->D1( ParOnSeam, P2d, SeamDer ); |
401 | //Curve1->D1( Par1, P2d, Der1 ); |
402 | //Curve2->D1( Par2, P2d, Der2 ); |
403 | Standard_Real Crossed1 = SeamDer ^ Der1; |
404 | Standard_Real Crossed2 = SeamDer ^ Der2; |
405 | //if (Crossed1 > 0 |
406 | } |
407 | */ |
408 | } |
409 | else // ! bp.IsVertex(2) |
410 | { |
411 | //Temporary the case of tangency is not implemented |
412 | Emap(CurEdge).Append( bp.Parameter(1) ); |
413 | ParsNonSeam(ind).Append( bp.Parameter(2) ); |
414 | Seam(ind).Append( CurEdge ); |
415 | ParsSeam(ind).Append( bp.Parameter(1) ); |
416 | } |
417 | } //for (; EInter.MorePoint(); EInter.NextPoint()) |
418 | } //for (; eit.More(); eit.Next()) |
419 | if (Wadd) |
420 | { |
421 | if (! WWmap.IsBound( CurWire )) |
422 | { |
423 | TopTools_ListOfShape emptylist; |
424 | WWmap.Bind( CurWire, emptylist ); |
425 | } |
426 | WWmap(CurWire).Append( aWire ); |
427 | } |
428 | } //if (! aWire.IsSame( CurWire )) |
429 | } //for (; wit.More(); wit.Next()) |
430 | } //for (i = 1; i <= Eseq.Length(); i++) |
431 | |
432 | //Sorting |
433 | for (i = 1; i <= NonSeam.Length(); i++) |
434 | for (j = 1; j < ParsNonSeam(i).Length(); j++) |
435 | for (k = j+1; k <= ParsNonSeam(i).Length(); k++) |
436 | if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j)) |
437 | { |
438 | Standard_Real temp = ParsNonSeam(i)(j); |
439 | ParsNonSeam(i)(j) = ParsNonSeam(i)(k); |
440 | ParsNonSeam(i)(k) = temp; |
441 | TopoDS_Shape tmp = Seam(i)(j); |
442 | Seam(i)(j) = Seam(i)(k); |
443 | Seam(i)(k) = tmp; |
444 | temp = ParsSeam(i)(j); |
445 | ParsSeam(i)(j) = ParsSeam(i)(k); |
446 | ParsSeam(i)(k) = temp; |
447 | } |
448 | BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap ); |
449 | for (; iter.More(); iter.Next()) |
450 | { |
451 | TColStd_SequenceOfReal Seq; |
452 | Seq = iter.Value(); |
453 | for (i = 1; i < Seq.Length(); i++) |
454 | for (j = i+1; j <= Seq.Length(); j++) |
455 | if (Seq(j) < Seq(i)) |
456 | { |
457 | Standard_Real temp = Seq(i); |
458 | Seq(i) = Seq(j); |
459 | Seq(j) = temp; |
460 | } |
461 | Emap( iter.Key() ) = Seq; |
462 | } |
463 | BRepFill_DataMapOfShapeSequenceOfReal EPmap; |
464 | TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam |
465 | TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it |
466 | iter.Initialize( Emap ); |
467 | for (; iter.More(); iter.Next()) |
468 | { |
469 | TColStd_SequenceOfReal parseq; |
470 | EPmap.Bind( iter.Key(), parseq ); |
471 | TopTools_SequenceOfShape shapeseq; |
472 | EVmap.Bind( iter.Key(), shapeseq ); |
473 | TopTools_SequenceOfShape shapeseq2; |
474 | EWmap.Bind( iter.Key(), shapeseq2 ); |
475 | } |
476 | |
477 | //Reconstruction of non-seam edges |
478 | BRepTools_Substitution aSub; |
479 | BRep_Builder BB; |
480 | for (i = 1; i <= NonSeam.Length(); i++) |
481 | { |
482 | TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) ); |
483 | TopTools_ListOfShape NewEdges; |
484 | TopoDS_Edge NewE; |
485 | TopoDS_Vertex Vfirst, Vlast; |
486 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
487 | Standard_Real par, FirstPar, LastPar; |
488 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
489 | Standard_Integer firstind = 1; |
490 | par = ParsNonSeam(i)(1); |
491 | TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) ); |
492 | //Find the face |
493 | for (j = 1; j <= Eseq.Length(); j++) |
494 | if (SeamEdge.IsSame( Eseq(j) )) |
495 | break; |
496 | TopoDS_Face theFace = TopoDS::Face( Fseq(j) ); |
497 | TopLoc_Location L; |
498 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L ); |
499 | if (Abs(par-FirstPar) <= Precision::Confusion()) |
500 | { |
501 | BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) ); |
502 | EPmap( SeamEdge ).Append( ParsSeam(i)(1) ); |
503 | EVmap( SeamEdge ).Append( Vfirst ); |
504 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
505 | firstind = 2; |
506 | } |
507 | Standard_Real prevpar = FirstPar; |
508 | TopoDS_Vertex PrevV = Vfirst; |
509 | for (j = firstind; j <= ParsNonSeam(i).Length(); j++) |
510 | { |
511 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
512 | NewE = TopoDS::Edge( aLocalShape ); |
513 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
514 | TopoDS_Vertex NewV; |
515 | par = ParsNonSeam(i)(j); |
516 | BB.Range( NewE, prevpar, par ); |
517 | SeamEdge = TopoDS::Edge( Seam(i)(j) ); |
518 | if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion()) |
519 | { |
520 | NewV = Vlast; |
521 | if (firstind == 2 && j == 2) |
522 | { |
523 | BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) ); |
524 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
525 | EVmap( SeamEdge ).Append( Vlast ); |
526 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
527 | break; |
528 | } |
529 | } |
530 | else |
531 | { |
532 | BRepAdaptor_Curve bcur( NewE ); |
533 | gp_Pnt Point = bcur.Value( par ); |
534 | NewV = BRepLib_MakeVertex( Point ); |
535 | BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() ); |
536 | } |
537 | BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() ); |
538 | NewE.Orientation( TopAbs_FORWARD ); |
539 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
540 | BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) ); |
541 | |
542 | NewEdges.Append( NewE ); |
543 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
544 | EVmap( SeamEdge ).Append( NewV ); |
545 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
546 | |
547 | prevpar = par; |
548 | PrevV = NewV; |
549 | } |
550 | //The last edge |
551 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
552 | NewE = TopoDS::Edge( aLocalShape ); |
553 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
554 | par = LastPar; |
555 | if (Abs(prevpar-par) > Precision::Confusion()) |
556 | { |
557 | BB.Range( NewE, prevpar, par ); |
558 | NewE.Orientation( TopAbs_FORWARD ); |
559 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
560 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
561 | NewEdges.Append( NewE ); |
562 | } |
563 | |
564 | //Substitute anEdge by NewEdges |
565 | aSub.Substitute( anEdge, NewEdges ); |
566 | } |
567 | |
568 | //Sorting of EPmap and EVmap and removing repeating points from them |
569 | iter.Initialize( EPmap ); |
570 | for (; iter.More(); iter.Next()) |
571 | { |
572 | TColStd_SequenceOfReal Seq; |
573 | Seq = iter.Value(); |
574 | TopTools_SequenceOfShape SeqShape; |
575 | SeqShape = EVmap( iter.Key() ); |
576 | TopTools_SequenceOfShape SeqShape2; |
577 | SeqShape2 = EWmap( iter.Key() ); |
578 | for (i = 1; i < Seq.Length(); i++) |
579 | for (j = i+1; j <= Seq.Length(); j++) |
580 | if (Seq(j) < Seq(i)) |
581 | { |
582 | Standard_Real temp = Seq(i); |
583 | Seq(i) = Seq(j); |
584 | Seq(j) = temp; |
585 | TopoDS_Shape tmp = SeqShape(i); |
586 | SeqShape(i) = SeqShape(j); |
587 | SeqShape(j) = tmp; |
588 | tmp = SeqShape2(i); |
589 | SeqShape2(i) = SeqShape2(j); |
590 | SeqShape2(j) = tmp; |
591 | } |
592 | EPmap( iter.Key() ) = Seq; |
593 | EVmap( iter.Key() ) = SeqShape; |
594 | EWmap( iter.Key() ) = SeqShape2; |
595 | } |
596 | iter.Initialize( EPmap ); |
597 | for (; iter.More(); iter.Next()) |
598 | { |
599 | TColStd_SequenceOfReal Seq; |
600 | Seq = iter.Value(); |
601 | TopTools_SequenceOfShape SeqShape; |
602 | SeqShape = EVmap( iter.Key() ); |
603 | TopTools_SequenceOfShape SeqShape2; |
604 | SeqShape2 = EWmap( iter.Key() ); |
605 | Standard_Boolean remove = Standard_True; |
606 | while (remove) |
607 | { |
608 | remove = Standard_False; |
609 | for (i = 1; i < Seq.Length(); i++) |
610 | if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion()) |
611 | { |
612 | Seq.Remove(i+1); |
613 | SeqShape.Remove(i+1); |
614 | SeqShape2.Remove(i+1); |
615 | remove = Standard_True; |
616 | } |
617 | } |
618 | EPmap( iter.Key() ) = Seq; |
619 | EVmap( iter.Key() ) = SeqShape; |
620 | EWmap( iter.Key() ) = SeqShape2; |
621 | } |
622 | |
623 | //Reconstruction of seam edges |
624 | TopTools_DataMapOfShapeShape VEmap; |
625 | iter.Initialize( Emap ); |
626 | for (; iter.More(); iter.Next()) |
627 | { |
628 | TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() ); |
629 | Standard_Boolean onepoint = Standard_False; |
630 | TopTools_ListOfShape NewEdges; |
631 | TColStd_SequenceOfReal Seq; |
632 | Seq = iter.Value(); |
633 | TColStd_SequenceOfReal Seq2; |
634 | Seq2 = EPmap( anEdge ); |
635 | TopTools_SequenceOfShape SeqVer; |
636 | SeqVer = EVmap( anEdge ); |
637 | TopTools_SequenceOfShape SeqWire; |
638 | SeqWire = EWmap( anEdge ); |
639 | TopoDS_Vertex Vfirst, Vlast; |
640 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
641 | Standard_Real fpar, lpar, FirstPar, LastPar; |
642 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
643 | fpar = FirstPar; |
644 | lpar = Seq(1); |
645 | TopoDS_Edge NewE; |
646 | Standard_Integer firstind = 1; |
647 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
648 | { |
649 | firstind = 2; |
650 | fpar = Seq(1); |
651 | lpar = Seq(2); |
652 | } |
653 | else |
654 | { |
655 | if (Seq.Length()%2 != 0) |
656 | { |
657 | VEmap.Bind( Vfirst, anEdge ); |
658 | firstind = 2; |
659 | fpar = Seq(1); |
660 | if (Seq.Length() > 2) |
661 | lpar = Seq(2); |
662 | else |
663 | onepoint = Standard_True; |
664 | } |
665 | } |
666 | if (!onepoint) |
667 | { |
668 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
669 | NewE = TopoDS::Edge( aLocalShape ); |
670 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
671 | BB.Range( NewE, fpar, lpar ); |
672 | NewE.Orientation( TopAbs_FORWARD ); |
673 | if (firstind == 1) |
674 | { |
675 | BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) ); |
676 | aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED); |
677 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
678 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) ); |
679 | } |
680 | else |
681 | { |
682 | aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD); |
683 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
684 | aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED); |
685 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
686 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) ); |
687 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) ); |
688 | } |
689 | NewEdges.Append( NewE ); |
690 | |
691 | firstind++; |
692 | for (i = firstind; i < Seq.Length(); i += 2) |
693 | { |
694 | aLocalShape = anEdge.EmptyCopied(); |
695 | NewE = TopoDS::Edge( aLocalShape ); |
696 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
697 | fpar = Seq(i); |
698 | lpar = Seq(i+1); |
699 | BB.Range( NewE, fpar, lpar ); |
700 | //Find vertices |
701 | for (j = 1; j <= Seq2.Length(); j++) |
702 | if (Abs(fpar-Seq2(j)) <= Precision::Confusion()) |
703 | break; |
704 | NewE.Orientation( TopAbs_FORWARD ); |
705 | TopoDS_Shape aLocalShape = SeqVer(j).Oriented(TopAbs_FORWARD); |
706 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
707 | aLocalShape = SeqVer(j+1).Oriented(TopAbs_REVERSED); |
708 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
709 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) ); |
710 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) ); |
711 | NewEdges.Append( NewE ); |
712 | } |
713 | } |
714 | |
715 | i = Seq.Length(); |
716 | fpar = Seq(i); |
717 | lpar = LastPar; |
718 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
719 | continue; |
720 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
721 | NewE = TopoDS::Edge( aLocalShape ); |
722 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
723 | BB.Range( NewE, fpar, lpar ); |
724 | NewE.Orientation( TopAbs_FORWARD ); |
725 | aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD); |
726 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
727 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) ); |
728 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
729 | NewEdges.Append( NewE ); |
730 | |
731 | //Substitute anEdge by NewEdges |
732 | aSub.Substitute( anEdge, NewEdges ); |
733 | } |
734 | |
735 | //Removing edges connected with missing extremities of seam edges |
736 | TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap ); |
737 | for (; itve.More(); itve.Next()) |
738 | { |
739 | TopoDS_Shape V = itve.Key(); |
740 | TopoDS_Shape E = itve.Value(); |
741 | TopoDS_Shape W; |
742 | for (i = 1; i <= Eseq.Length(); i++) |
743 | if (E.IsSame( Eseq(i) )) |
744 | { |
745 | W = Wseq(i); |
746 | break; |
747 | } |
748 | TopoDS_Shape Etoremove; |
749 | eit.Initialize( W ); |
750 | for (; eit.More(); eit.Next()) |
751 | { |
752 | TopoDS_Edge CurE = TopoDS::Edge( eit.Value() ); |
753 | if (CurE.IsSame( E )) |
754 | continue; |
755 | TopoDS_Vertex Vfirst, Vlast; |
756 | TopExp::Vertices( CurE, Vfirst, Vlast ); |
757 | if (Vfirst.IsSame( V ) || Vlast.IsSame( V )) |
758 | { |
759 | Etoremove = CurE; |
760 | break; |
761 | } |
762 | } |
763 | if (! Etoremove.IsNull()) |
764 | { |
765 | W.Free( Standard_True ); |
766 | BB.Remove( W, Etoremove ); |
767 | } |
768 | } |
769 | |
770 | aSub.Build( myShape ); |
771 | if (aSub.IsCopied( myShape )) |
772 | { |
773 | const TopTools_ListOfShape& listSh = aSub.Copy( myShape ); |
774 | if (! listSh.IsEmpty()) |
775 | myShape = listSh.First(); |
776 | } |
777 | |
778 | //Reconstruction of wires |
779 | TopTools_ListOfShape theCopy; |
780 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap ); |
781 | for (; itww.More(); itww.Next()) |
782 | { |
783 | CurWire = itww.Key(); |
784 | theCopy = aSub.Copy( CurWire ); |
785 | CurWire = theCopy.First(); |
786 | CurWire.Free( Standard_True ); |
787 | TopTools_ListIteratorOfListOfShape itl( itww.Value() ); |
788 | for (; itl.More(); itl.Next()) |
789 | { |
790 | TopoDS_Shape aWire = itl.Value(); |
791 | CurFace = WFmap( aWire ); |
792 | theCopy = aSub.Copy( aWire ); |
793 | aWire = theCopy.First(); |
794 | //Adjusting period |
795 | TopLoc_Location L; |
796 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L ); |
797 | eit.Initialize( aWire ); |
798 | for (; eit.More(); eit.Next()) |
799 | { |
800 | TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() ); |
801 | gp_Pnt2d Pfirst, Plast, Pmid; |
802 | BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast ); |
803 | BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) ); |
804 | Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. ); |
805 | gp_Vec2d offset; |
806 | Standard_Boolean translate = Standard_False; |
807 | if (Pfirst.X()-2.*PI > Precision::Confusion() || |
808 | Plast.X()-2.*PI > Precision::Confusion() || |
809 | Pmid.X()-2.*PI > Precision::Confusion()) |
810 | { |
811 | offset.SetCoord( -2.*PI, 0 ); |
812 | translate = Standard_True; |
813 | } |
814 | if (Pfirst.X() < -Precision::Confusion() || |
815 | Plast.X() < -Precision::Confusion() || |
816 | Pmid.X() < -Precision::Confusion()) |
817 | { |
818 | offset.SetCoord( 2.*PI, 0 ); |
819 | translate = Standard_True; |
820 | } |
821 | if (translate) |
822 | { |
823 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape()); |
824 | BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() ); |
825 | Handle(BRep_GCurve) GC; |
826 | |
827 | for (; itcr.More(); itcr.Next()) |
828 | { |
829 | GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
830 | if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L )) |
831 | { |
832 | Handle(Geom2d_Curve) PC = GC->PCurve(); |
833 | PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) ); |
834 | GC->PCurve( PC ); |
835 | TE->ChangeCurves().Remove( itcr ); |
836 | TE->ChangeCurves().Append( GC ); |
837 | break; |
838 | } |
839 | } |
840 | } |
841 | } |
842 | /////////////////// |
843 | eit.Initialize( aWire, Standard_False ); |
844 | for (; eit.More(); eit.Next()) |
845 | { |
846 | TopoDS_Shape anEdge = eit.Value(); |
847 | BB.Add( CurWire, anEdge ); |
848 | } |
849 | if (aSub.IsCopied( CurFace )) |
850 | { |
851 | theCopy = aSub.Copy( CurFace ); |
852 | CurFace = theCopy.First(); |
853 | } |
854 | CurFace.Free( Standard_True ); |
855 | BB.Remove( CurFace, aWire ); |
856 | } |
857 | } |
858 | } |