0030480: Visualization - Clear of Select3D_SensitiveGroup does not update internal...
[occt.git] / src / ShapeFix / ShapeFix_SplitCommonVertex.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <gp_Pnt.hxx>
18 #include <Message_Msg.hxx>
19 #include <ShapeAnalysis_Edge.hxx>
20 #include <ShapeBuild_Edge.hxx>
21 #include <ShapeBuild_ReShape.hxx>
22 #include <ShapeExtend.hxx>
23 #include <ShapeExtend_WireData.hxx>
24 #include <ShapeFix_SplitCommonVertex.hxx>
25 #include <Standard_Type.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Wire.hxx>
34 #include <TopTools_DataMapOfShapeShape.hxx>
35 #include <TopTools_SequenceOfShape.hxx>
36
37 IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_SplitCommonVertex,ShapeFix_Root)
38
39 //=======================================================================
40 //function : ShapeFix_SplitCommonVertex
41 //purpose  : 
42 //=======================================================================
43 ShapeFix_SplitCommonVertex::ShapeFix_SplitCommonVertex()
44 {
45   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
46   SetPrecision(Precision::Confusion());
47 }
48
49
50 //=======================================================================
51 //function : Init
52 //purpose  : 
53 //=======================================================================
54
55 void ShapeFix_SplitCommonVertex::Init(const TopoDS_Shape& S) 
56 {
57   myShape = S;
58   if ( Context().IsNull() ) 
59     SetContext ( new ShapeBuild_ReShape );
60   myResult = myShape;
61   Context()->Apply(myShape);
62 }
63
64
65 //=======================================================================
66 //function : Perform
67 //purpose  : 
68 //=======================================================================
69
70 void ShapeFix_SplitCommonVertex::Perform() 
71 {
72   TopAbs_ShapeEnum st = myShape.ShapeType();
73   if(st>TopAbs_FACE) return;
74   for(TopExp_Explorer itf(myShape,TopAbs_FACE); itf.More(); itf.Next()) {
75     TopoDS_Shape tmpFace = Context()->Apply(itf.Current());
76     TopoDS_Face F = TopoDS::Face(tmpFace);
77     if(F.IsNull()) continue;
78     // analys face and split if necessary
79     TopTools_SequenceOfShape wires;
80     for(TopoDS_Iterator itw(F,Standard_False); itw.More(); itw.Next()) {
81       if(itw.Value().ShapeType() != TopAbs_WIRE)
82         continue;
83       wires.Append(itw.Value());
84     }
85     if(wires.Length()<2) continue;
86     TopTools_DataMapOfShapeShape MapVV;
87     MapVV.Clear();
88     for(Standard_Integer nw1=1; nw1<wires.Length(); nw1++) {
89       TopoDS_Wire w1 = TopoDS::Wire(wires.Value(nw1));
90       Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(w1);
91       for(Standard_Integer nw2=nw1+1; nw2<=wires.Length(); nw2++) {
92         TopoDS_Wire w2 = TopoDS::Wire(wires.Value(nw2));
93         Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(w2);
94
95         for(TopExp_Explorer expv1(w1,TopAbs_VERTEX); expv1.More(); expv1.Next()) {
96           TopoDS_Vertex V1 = TopoDS::Vertex(expv1.Current());
97           for(TopExp_Explorer expv2(w2,TopAbs_VERTEX); expv2.More(); expv2.Next()) {
98             TopoDS_Vertex V2 = TopoDS::Vertex(expv2.Current());
99             if(V1==V2) {
100               // common vertex exists
101               TopoDS_Vertex Vnew;
102               if(MapVV.IsBound(V2)) {
103                 Vnew = TopoDS::Vertex(MapVV.Find(V2));
104               }
105               else {
106                 gp_Pnt P = BRep_Tool::Pnt(V2);
107                 Standard_Real tol = BRep_Tool::Tolerance(V2);
108                 BRep_Builder B;
109                 B.MakeVertex(Vnew,P,tol);
110                 MapVV.Bind(V2,Vnew);
111               }
112               ShapeBuild_Edge sbe;
113               ShapeAnalysis_Edge sae;
114               for(Standard_Integer ne2=1; ne2<=sewd2->NbEdges(); ne2++) {
115                 TopoDS_Edge E = sewd2->Edge(ne2);
116                 TopoDS_Vertex FV = sae.FirstVertex(E);
117                 TopoDS_Vertex LV = sae.LastVertex(E);
118                 Standard_Boolean IsCoinc = Standard_False;
119                 if(FV==V2) {
120                   FV=Vnew;
121                   IsCoinc = Standard_True;
122                 }
123                 if(LV==V2) {
124                   LV=Vnew;
125                   IsCoinc = Standard_True;
126                 }
127                 if(IsCoinc) {
128                   TopoDS_Edge NewE = sbe.CopyReplaceVertices(E,FV,LV);
129                   Context()->Replace(E,NewE);
130                 }
131               }
132             }
133           }
134         }
135
136       }
137     }
138     if ( !MapVV.IsEmpty() )
139       SendWarning( Message_Msg( "Fix.SplitCommonVertex.MSG0" ));
140   }
141
142   myShape = Context()->Apply(myShape);  
143
144 }
145
146
147 //=======================================================================
148 //function : Shape
149 //purpose  : 
150 //=======================================================================
151
152 TopoDS_Shape ShapeFix_SplitCommonVertex::Shape() 
153 {
154   return myShape;
155 }
156