1 // Created on: 1998-06-03
2 // Created by: data exchange team
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #ifndef _ShapeFix_Wire_HeaderFile
18 #define _ShapeFix_Wire_HeaderFile
20 #include <Standard.hxx>
21 #include <Standard_Type.hxx>
23 #include <Standard_Boolean.hxx>
24 #include <Standard_Integer.hxx>
25 #include <Standard_Real.hxx>
26 #include <ShapeFix_Root.hxx>
27 #include <TopoDS_Wire.hxx>
28 #include <ShapeExtend_Status.hxx>
30 class ShapeAnalysis_Wire;
33 class ShapeExtend_WireData;
35 class TopLoc_Location;
36 class ShapeAnalysis_WireOrder;
40 DEFINE_STANDARD_HANDLE(ShapeFix_Wire, ShapeFix_Root)
42 //! This class provides a set of tools for repairing a wire.
44 //! These are methods Fix...(), organised in two levels:
46 //! Level 1: Advanced - each method in this level fixes one separate problem,
47 //! usually dealing with either single edge or connection of the
48 //! two adjacent edges. These methods should be used carefully and
49 //! called in right sequence, because some of them depend on others.
51 //! Level 2: Public (API) - methods which group several methods of level 1
52 //! and call them in a proper sequence in order to make some
53 //! consistent set of fixes for a whole wire. It is possible to
54 //! control calls to methods of the advanced level from methods of
55 //! the public level by use of flags Fix..Mode() (see below).
57 //! Fixes can be made in three ways:
58 //! 1. Increasing tolerance of an edge or a vertex
59 //! 2. Changing topology (adding/removing/replacing edge in the wire
60 //! and/or replacing the vertex in the edge)
61 //! 3. Changing geometry (shifting vertex or adjusting ends of edge
62 //! curve to vertices, or recomputing curves of the edge)
64 //! When fix can be made in more than one way (e.g., either
65 //! by increasing tolerance or shifting a vertex), it is choosen
66 //! according to the flags:
67 //! ModifyTopologyMode - allows modification of the topology.
68 //! This flag can be set when fixing a wire on
69 //! the separate (free) face, and should be
70 //! unset for face which is part of shell.
71 //! ModifyGeometryMode - allows modification of the geometry.
73 //! The order of descriptions of Fix() methods in this CDL
74 //! approximately corresponds to the optimal order of calls.
76 //! NOTE: most of fixing methods expect edges in the
77 //! ShapeExtend_WireData to be ordered, so it is necessary to make
78 //! call to FixReorder() before any other fixes
80 //! ShapeFix_Wire should be initialized prior to any fix by the
82 //! a) Wire (ether TopoDS_Wire or ShapeExtend_Wire)
83 //! b) Face or surface
85 //! d) Maximal tail angle and width
86 //! This can be done either by calling corresponding methods
87 //! (LoadWire, SetFace or SetSurface, SetPrecision, SetMaxTailAngle
88 //! and SetMaxTailWidth), or
89 //! by loading already filled ShapeAnalisis_Wire with method Load
90 class ShapeFix_Wire : public ShapeFix_Root
96 //! Empty Constructor, creates clear object with default flags
97 Standard_EXPORT ShapeFix_Wire();
99 //! Create new object with default flags and prepare it for use
100 //! (Loads analyzer with all the data for the wire and face)
101 Standard_EXPORT ShapeFix_Wire(const TopoDS_Wire& wire, const TopoDS_Face& face, const Standard_Real prec);
103 //! Sets all modes to default
104 Standard_EXPORT void ClearModes();
106 //! Clears all statuses
107 Standard_EXPORT void ClearStatuses();
109 //! Load analyzer with all the data for the wire and face
110 //! and drops all fixing statuses
111 Standard_EXPORT void Init (const TopoDS_Wire& wire, const TopoDS_Face& face, const Standard_Real prec);
113 //! Load analyzer with all the data already prepared
114 //! and drops all fixing statuses
115 //! If analyzer contains face, there is no need to set it
116 //! by SetFace or SetSurface
117 Standard_EXPORT void Init (const Handle(ShapeAnalysis_Wire)& saw);
119 //! Load data for the wire, and drops all fixing statuses
120 Standard_EXPORT void Load (const TopoDS_Wire& wire);
122 //! Load data for the wire, and drops all fixing statuses
123 Standard_EXPORT void Load (const Handle(ShapeExtend_WireData)& sbwd);
125 //! Set working face for the wire
126 void SetFace (const TopoDS_Face& face);
128 //! Set surface for the wire
129 void SetSurface (const Handle(Geom_Surface)& surf);
131 //! Set surface for the wire
132 void SetSurface (const Handle(Geom_Surface)& surf, const TopLoc_Location& loc);
134 //! Set working precision (to root and to analyzer)
135 Standard_EXPORT virtual void SetPrecision (const Standard_Real prec) Standard_OVERRIDE;
137 //! Sets the maximal allowed angle of the tails in radians.
138 Standard_EXPORT void SetMaxTailAngle (const Standard_Real theMaxTailAngle);
140 //! Sets the maximal allowed width of the tails.
141 Standard_EXPORT void SetMaxTailWidth (const Standard_Real theMaxTailWidth);
143 //! Tells if the wire is loaded
144 Standard_Boolean IsLoaded() const;
146 //! Tells if the wire and face are loaded
147 Standard_Boolean IsReady() const;
149 //! returns number of edges in the working wire
150 Standard_EXPORT Standard_Integer NbEdges() const;
152 //! Makes the resulting Wire (by basic Brep_Builder)
153 TopoDS_Wire Wire() const;
155 //! Makes the resulting Wire (by BRepAPI_MakeWire)
156 TopoDS_Wire WireAPIMake() const;
158 //! returns field Analyzer (working tool)
159 Handle(ShapeAnalysis_Wire) Analyzer() const;
161 //! returns working wire
162 const Handle(ShapeExtend_WireData)& WireData() const;
164 //! returns working face (Analyzer.Face())
165 const TopoDS_Face& Face() const;
167 //! Returns (modifiable) the flag which defines whether it is
168 //! allowed to modify topology of the wire during fixing
169 //! (adding/removing edges etc.)
170 Standard_Boolean& ModifyTopologyMode();
172 //! Returns (modifiable) the flag which defines whether the Fix..()
173 //! methods are allowed to modify geometry of the edges and vertices
174 Standard_Boolean& ModifyGeometryMode();
176 //! Returns (modifiable) the flag which defines whether the Fix..()
177 //! methods are allowed to modify RemoveLoop of the edges
178 Standard_Integer& ModifyRemoveLoopMode();
180 //! Returns (modifiable) the flag which defines whether the wire
181 //! is to be closed (by calling methods like FixDegenerated()
182 //! and FixConnected() for last and first edges).
183 Standard_Boolean& ClosedWireMode();
185 //! Returns (modifiable) the flag which defines whether the 2d (True)
186 //! representation of the wire is preferable over 3d one (in the
187 //! case of ambiguity in FixEdgeCurves).
188 Standard_Boolean& PreferencePCurveMode();
190 //! Returns (modifiable) the flag which defines whether tool
191 //! tries to fix gaps first by changing curves ranges (i.e.
192 //! using intersection, extrema, projections) or not.
193 Standard_Boolean& FixGapsByRangesMode();
195 Standard_Integer& FixReorderMode();
197 Standard_Integer& FixSmallMode();
199 Standard_Integer& FixConnectedMode();
201 Standard_Integer& FixEdgeCurvesMode();
203 Standard_Integer& FixDegeneratedMode();
205 Standard_Integer& FixSelfIntersectionMode();
207 Standard_Integer& FixLackingMode();
209 Standard_Integer& FixGaps3dMode();
211 //! Returns (modifiable) the flag for corresponding Fix..() method
212 //! which defines whether this method will be called from the
215 //! 1 method will be called
216 //! 0 method will not be called
217 Standard_Integer& FixGaps2dMode();
219 Standard_Integer& FixReversed2dMode();
221 Standard_Integer& FixRemovePCurveMode();
223 Standard_Integer& FixAddPCurveMode();
225 Standard_Integer& FixRemoveCurve3dMode();
227 Standard_Integer& FixAddCurve3dMode();
229 Standard_Integer& FixSeamMode();
231 Standard_Integer& FixShiftedMode();
233 Standard_Integer& FixSameParameterMode();
235 Standard_Integer& FixVertexToleranceMode();
237 Standard_Integer& FixNotchedEdgesMode();
239 Standard_Integer& FixSelfIntersectingEdgeMode();
241 Standard_Integer& FixIntersectingEdgesMode();
243 //! Returns (modifiable) the flag for corresponding Fix..() method
244 //! which defines whether this method will be called from the
245 //! corresponding Fix..() method of the public level:
247 //! 1 method will be called
248 //! 0 method will not be called
249 Standard_Integer& FixNonAdjacentIntersectingEdgesMode();
251 Standard_Integer& FixTailMode();
253 //! This method performs all the available fixes.
254 //! If some fix is turned on or off explicitly by the Fix..Mode() flag,
255 //! this fix is either called or not depending on that flag.
256 //! Else (i.e. if flag is default) fix is called depending on the
257 //! situation: some fixes are not called or are limited if order of
258 //! edges in the wire is not OK, or depending on modes
260 //! The order of the fixes and default behaviour of Perform() are:
262 //! FixSmall (with lockvtx true if ! TopoMode or if wire is not ordered)
263 //! FixConnected (if wire is ordered)
264 //! FixEdgeCurves (without FixShifted if wire is not ordered)
265 //! FixDegenerated (if wire is ordered)
266 //! FixSelfIntersection (if wire is ordered and ClosedMode is True)
267 //! FixLacking (if wire is ordered)
268 Standard_EXPORT Standard_Boolean Perform();
270 //! Performs an analysis and reorders edges in the wire using
272 Standard_EXPORT Standard_Boolean FixReorder();
274 //! Applies FixSmall(num) to all edges in the wire
275 Standard_EXPORT Standard_Integer FixSmall (const Standard_Boolean lockvtx, const Standard_Real precsmall = 0.0);
277 //! Applies FixConnected(num) to all edges in the wire
278 //! Connection between first and last edges is treated only if
279 //! flag ClosedMode is True
280 //! If <prec> is -1 then MaxTolerance() is taken.
281 Standard_EXPORT Standard_Boolean FixConnected (const Standard_Real prec = -1.0);
283 //! Groups the fixes dealing with 3d and pcurves of the edges.
284 //! The order of the fixes and the default behaviour are:
285 //! ShapeFix_Edge::FixReversed2d
286 //! ShapeFix_Edge::FixRemovePCurve (only if forced)
287 //! ShapeFix_Edge::FixAddPCurve
288 //! ShapeFix_Edge::FixRemoveCurve3d (only if forced)
289 //! ShapeFix_Edge::FixAddCurve3d
292 //! ShapeFix_Edge::FixSameParameter
293 Standard_EXPORT Standard_Boolean FixEdgeCurves();
295 //! Applies FixDegenerated(num) to all edges in the wire
296 //! Connection between first and last edges is treated only if
297 //! flag ClosedMode is True
298 Standard_EXPORT Standard_Boolean FixDegenerated();
300 //! Applies FixSelfIntersectingEdge(num) and
301 //! FixIntersectingEdges(num) to all edges in the wire and
302 //! FixIntersectingEdges(num1, num2) for all pairs num1 and num2
303 //! such that num2 >= num1 + 2
304 //! and removes wrong edges if any
305 Standard_EXPORT Standard_Boolean FixSelfIntersection();
307 //! Applies FixLacking(num) to all edges in the wire
308 //! Connection between first and last edges is treated only if
309 //! flag ClosedMode is True
310 //! If <force> is False (default), test for connectness is done with
311 //! precision of vertex between edges, else it is done with minimal
312 //! value of vertex tolerance and Analyzer.Precision().
313 //! Hence, <force> will lead to inserting lacking edges in replacement
314 //! of vertices which have big tolerances.
315 Standard_EXPORT Standard_Boolean FixLacking (const Standard_Boolean force = Standard_False);
317 //! Fixes a wire to be well closed
318 //! It performs FixConnected, FixDegenerated and FixLacking between
319 //! last and first edges (independingly on flag ClosedMode and modes
320 //! for these fixings)
321 //! If <prec> is -1 then MaxTolerance() is taken.
322 Standard_EXPORT Standard_Boolean FixClosed (const Standard_Real prec = -1.0);
324 //! Fixes gaps between ends of 3d curves on adjacent edges
325 //! myPrecision is used to detect the gaps.
326 Standard_EXPORT Standard_Boolean FixGaps3d();
328 //! Fixes gaps between ends of pcurves on adjacent edges
329 //! myPrecision is used to detect the gaps.
330 Standard_EXPORT Standard_Boolean FixGaps2d();
332 //! Reorder edges in the wire as determined by WireOrder
333 //! that should be filled and computed before
334 Standard_EXPORT Standard_Boolean FixReorder (const ShapeAnalysis_WireOrder& wi);
336 //! Fixes Null Length Edge to be removed
337 //! If an Edge has Null Length (regarding preci, or <precsmall>
338 //! - what is smaller), it should be removed
339 //! It can be with no problem if its two vertices are the same
340 //! Else, if lockvtx is False, it is removed and its end vertex
341 //! is put on the preceeding edge
342 //! But if lockvtx is True, this edge must be kept ...
343 Standard_EXPORT Standard_Boolean FixSmall (const Standard_Integer num, const Standard_Boolean lockvtx, const Standard_Real precsmall);
345 //! Fixes connected edges (preceeding and current)
346 //! Forces Vertices (end of preceeding-begin of current) to be
348 //! Tests with starting preci or, if given greater, <prec>
349 //! If <prec> is -1 then MaxTolerance() is taken.
350 Standard_EXPORT Standard_Boolean FixConnected (const Standard_Integer num, const Standard_Real prec);
352 //! Fixes a seam edge
353 //! A Seam edge has two pcurves, one for forward. one for reversed
354 //! The forward pcurve must be set as first
356 //! NOTE that correct order of pcurves in the seam edge depends on
357 //! its orientation (i.e., on orientation of the wire, method of
358 //! exploration of edges etc.).
359 //! Since wire represented by the ShapeExtend_WireData is always forward
360 //! (orientation is accounted by edges), it will work correct if:
361 //! 1. Wire created from ShapeExtend_WireData with methods
362 //! ShapeExtend_WireData::Wire..() is added into the FORWARD face
363 //! (orientation can be applied later)
364 //! 2. Wire is extracted from the face with orientation not composed
365 //! with orientation of the face
366 Standard_EXPORT Standard_Boolean FixSeam (const Standard_Integer num);
368 //! Fixes edges which have pcurves shifted by whole parameter
369 //! range on the closed surface (the case may occur if pcurve
370 //! of edge was computed by projecting 3d curve, which goes
372 //! It compares each two consequent edges and tries to connect them
373 //! if distance between ends is near to range of the surface.
374 //! It also can detect and fix the case if all pcurves are connected,
375 //! but lie out of parametric bounds of the surface.
376 //! In addition to FixShifted from ShapeFix_Wire, more
377 //! sophisticated check of degenerate points is performed,
378 //! and special cases like sphere given by two meridians
380 Standard_EXPORT Standard_Boolean FixShifted();
382 //! Fixes Degenerated Edge
383 //! Checks an <num-th> edge or a point between <num>th-1 and <num>th
384 //! edges for a singularity on a supporting surface.
385 //! If singularity is detected, either adds new degenerated edge
386 //! (before <num>th), or makes <num>th edge to be degenerated.
387 Standard_EXPORT Standard_Boolean FixDegenerated (const Standard_Integer num);
389 //! Fixes Lacking Edge
390 //! Test if two adjucent edges are disconnected in 2d (while
391 //! connected in 3d), and in that case either increase tolerance
392 //! of the vertex or add a new edge (straight in 2d space), in
393 //! order to close wire in 2d.
394 //! Returns True if edge was added or tolerance was increased.
395 Standard_EXPORT Standard_Boolean FixLacking (const Standard_Integer num, const Standard_Boolean force = Standard_False);
397 Standard_EXPORT Standard_Boolean FixNotchedEdges();
399 //! Fixes gap between ends of 3d curves on num-1 and num-th edges.
400 //! myPrecision is used to detect the gap.
401 //! If convert is True, converts curves to bsplines to bend.
402 Standard_EXPORT Standard_Boolean FixGap3d (const Standard_Integer num, const Standard_Boolean convert = Standard_False);
404 //! Fixes gap between ends of pcurves on num-1 and num-th edges.
405 //! myPrecision is used to detect the gap.
406 //! If convert is True, converts pcurves to bsplines to bend.
407 Standard_EXPORT Standard_Boolean FixGap2d (const Standard_Integer num, const Standard_Boolean convert = Standard_False);
409 Standard_EXPORT Standard_Boolean FixTails();
411 Standard_Boolean StatusReorder (const ShapeExtend_Status status) const;
413 Standard_Boolean StatusSmall (const ShapeExtend_Status status) const;
415 Standard_Boolean StatusConnected (const ShapeExtend_Status status) const;
417 Standard_Boolean StatusEdgeCurves (const ShapeExtend_Status status) const;
419 Standard_Boolean StatusDegenerated (const ShapeExtend_Status status) const;
421 Standard_Boolean StatusSelfIntersection (const ShapeExtend_Status status) const;
423 Standard_Boolean StatusLacking (const ShapeExtend_Status status) const;
425 Standard_Boolean StatusClosed (const ShapeExtend_Status status) const;
427 Standard_Boolean StatusGaps3d (const ShapeExtend_Status status) const;
429 Standard_Boolean StatusGaps2d (const ShapeExtend_Status status) const;
431 Standard_Boolean StatusNotches (const ShapeExtend_Status status) const;
433 //! Querying the status of perfomed API fixing procedures
434 //! Each Status..() methods gives information about the last call to
435 //! the corresponding Fix..() method of API level:
436 //! OK : no problems detected; nothing done
437 //! DONE: some problem(s) was(were) detected and successfully fixed
438 //! FAIL: some problem(s) cannot be fixed
439 Standard_Boolean StatusRemovedSegment() const;
441 Standard_Boolean StatusFixTails (const ShapeExtend_Status status) const;
443 //! Queries the status of last call to methods Fix... of
445 //! For details see corresponding methods; universal statuses are:
446 //! OK : problem not detected; nothing done
447 //! DONE: problem was detected and successfully fixed
448 //! FAIL: problem cannot be fixed
449 Standard_Boolean LastFixStatus (const ShapeExtend_Status status) const;
451 //! Returns tool for fixing wires.
452 Handle(ShapeFix_Edge) FixEdgeTool() const;
457 DEFINE_STANDARD_RTTIEXT(ShapeFix_Wire,ShapeFix_Root)
462 //! Updates WireData if some replacements are made
463 //! This is necessary for wires (unlike other shape types)
464 //! since one edge can present in wire several times
465 Standard_EXPORT void UpdateWire();
467 Handle(ShapeFix_Edge) myFixEdge;
468 Handle(ShapeAnalysis_Wire) myAnalyzer;
469 Standard_Boolean myGeomMode;
470 Standard_Boolean myTopoMode;
471 Standard_Boolean myClosedMode;
472 Standard_Boolean myPreference2d;
473 Standard_Boolean myFixGapsByRanges;
474 Standard_Integer myFixReversed2dMode;
475 Standard_Integer myFixRemovePCurveMode;
476 Standard_Integer myFixAddPCurveMode;
477 Standard_Integer myFixRemoveCurve3dMode;
478 Standard_Integer myFixAddCurve3dMode;
479 Standard_Integer myFixSeamMode;
480 Standard_Integer myFixShiftedMode;
481 Standard_Integer myFixSameParameterMode;
482 Standard_Integer myFixVertexToleranceMode;
483 Standard_Integer myFixNotchedEdgesMode;
484 Standard_Integer myFixSelfIntersectingEdgeMode;
485 Standard_Integer myFixIntersectingEdgesMode;
486 Standard_Integer myFixNonAdjacentIntersectingEdgesMode;
487 Standard_Integer myFixTailMode;
488 Standard_Integer myRemoveLoopMode;
489 Standard_Integer myFixReorderMode;
490 Standard_Integer myFixSmallMode;
491 Standard_Integer myFixConnectedMode;
492 Standard_Integer myFixEdgeCurvesMode;
493 Standard_Integer myFixDegeneratedMode;
494 Standard_Integer myFixSelfIntersectionMode;
495 Standard_Integer myFixLackingMode;
496 Standard_Integer myFixGaps3dMode;
497 Standard_Integer myFixGaps2dMode;
498 Standard_Integer myLastFixStatus;
499 Standard_Integer myStatusReorder;
500 Standard_Integer myStatusSmall;
501 Standard_Integer myStatusConnected;
502 Standard_Integer myStatusEdgeCurves;
503 Standard_Integer myStatusDegenerated;
504 Standard_Integer myStatusClosed;
505 Standard_Integer myStatusSelfIntersection;
506 Standard_Integer myStatusLacking;
507 Standard_Integer myStatusGaps3d;
508 Standard_Integer myStatusGaps2d;
509 Standard_Boolean myStatusRemovedSegment;
510 Standard_Integer myStatusNotches;
511 Standard_Integer myStatusFixTails;
512 Standard_Real myMaxTailAngleSine;
513 Standard_Real myMaxTailWidth;
519 //! Detect and fix self-intersecting pcurve of edge <num>.
520 //! Fix is made by one of two methods:
521 //! - cut out the self-intersection loop on pcurve (thus
522 //! producing C0 pcurve). This also increases tolerance of edge
523 //! in order to satisfy SameParameter requirement.
524 //! - increase tolerance of the vertex of edge nearest to the
525 //! self-intersection point so that it comprises that point.
526 //! The first method is considered only if ModifyGeometryMode
527 //! is True. In that case, the method which requires less
528 //! increasing of tolerance is selected.
529 Standard_EXPORT Standard_Boolean FixSelfIntersectingEdge (const Standard_Integer num);
531 //! Test if two consequent edges are intersecting and fix it
532 //! by increasing of tolerance of vertex between edges,
533 //! shifting this vertex to the point of intersection,
534 //! cutting edges to the intersection point.
535 //! It also can give signal to remove edge if it whole is cut by
536 //! intersection (if flag ModifyTopologyMode is set).
537 Standard_EXPORT Standard_Boolean FixIntersectingEdges (const Standard_Integer num);
539 //! Tests if two edges <num1> and <num2> are intersecting and
540 //! fix intersection by increasing of tolerance of vertex
541 //! nearest to the point of intersection.
542 Standard_EXPORT Standard_Boolean FixIntersectingEdges (const Standard_Integer num1, const Standard_Integer num2);
544 Standard_EXPORT void FixDummySeam (const Standard_Integer num);
551 #include <ShapeFix_Wire.lxx>
557 #endif // _ShapeFix_Wire_HeaderFile