0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / ShapeCustom / ShapeCustom_DirectModification.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 //:l8 abv 15.01.99: CTS22022: writing correct pcurves for indirect tori
15 //:p5 abv 26.02.99: PRO18207: force copying of edge if any its pcurve is to be replaced
16 //szv#4 S4163
17 //S4181 pdn 20.04.99 Modification of indirect rectangular trimming surfaces and taking
18 // locations into account
19 //szv 03.01.01 PositiveCones merged in
20
21 #include <BRep_Builder.hxx>
22 #include <BRep_GCurve.hxx>
23 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
24 #include <BRep_TEdge.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepTools.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom_ConicalSurface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_ElementarySurface.hxx>
31 #include <Geom_RectangularTrimmedSurface.hxx>
32 #include <Geom_Surface.hxx>
33 #include <gp_Mat.hxx>
34 #include <gp_Pnt.hxx>
35 #include <Message_Msg.hxx>
36 #include <Precision.hxx>
37 #include <ShapeCustom_DirectModification.hxx>
38 #include <Standard_Type.hxx>
39 #include <TopLoc_Location.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Vertex.hxx>
44
45 IMPLEMENT_STANDARD_RTTIEXT(ShapeCustom_DirectModification,ShapeCustom_Modification)
46
47 //=======================================================================
48 //function : ShapeCustom_DirectModification
49 //purpose  : 
50 //=======================================================================
51 ShapeCustom_DirectModification::ShapeCustom_DirectModification()
52 {
53 }
54
55 //S4181 returns 0 - none, 1 - indirect, 2 - negative cone, 3 - indirect negative cone
56 static Standard_Integer IsIndirectSurface (Handle(Geom_Surface) &S,
57                                            TopLoc_Location &L)
58 {
59   Standard_Integer result = 0;
60
61   Handle(Geom_Surface) TS = S;
62   while (TS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
63     TS = Handle(Geom_RectangularTrimmedSurface)::DownCast(TS)->BasisSurface();
64
65   Handle(Geom_ElementarySurface) ES = Handle(Geom_ElementarySurface)::DownCast(TS);
66   if (!ES.IsNull()) {
67     // is the surface indirect ?
68     gp_Trsf t = L.Transformation();
69     Standard_Boolean neg = t.IsNegative();
70     Standard_Boolean det = ( t.VectorialPart().Determinant() < 0.0 );
71     Standard_Boolean dir = ES->Position().Direct();
72     if ((neg != det) == dir) result = 1;
73     Handle(Geom_ConicalSurface) CS = Handle(Geom_ConicalSurface)::DownCast(ES);
74     if (!CS.IsNull()) {
75       // does the cone have negative semiangle ?
76       if ( CS->SemiAngle() < 0.0 ) result += 2;
77     }
78     if (result) S = TS;
79   }
80
81   return result;
82 }
83
84 //=======================================================================
85 //function : NewSurface
86 //purpose  : 
87 //=======================================================================
88
89 Standard_Boolean ShapeCustom_DirectModification::NewSurface (const TopoDS_Face& F,
90                                                              Handle(Geom_Surface)& S,
91                                                              TopLoc_Location& L,
92                                                              Standard_Real& Tol,
93                                                              Standard_Boolean& RevWires,
94                                                              Standard_Boolean& RevFace)
95 {
96   S = BRep_Tool::Surface(F,L);
97   
98   switch (IsIndirectSurface(S,L)) {
99     case 1: { // Indirect surface
100       // UReverse a copy of S
101       S = S->UReversed();
102       RevWires = Standard_True;
103       RevFace = Standard_True;
104       break;
105     }
106     case 2: { // Negative cone
107       // U- and VReverse a copy of S
108       S = S->VReversed();
109       S->UReverse();
110       RevWires = Standard_False;
111       RevFace = Standard_False;
112       break;
113     }
114     case 3: { // Indirect negative cone
115       // VReverse a copy of S
116       S = S->VReversed();
117       RevWires = Standard_True;
118       RevFace = Standard_True;
119       break;
120     }
121     default: return Standard_False;
122   }
123
124   SendMsg( F, Message_Msg("DirectModification.NewSurface.MSG0"));
125
126   Tol = BRep_Tool::Tolerance(F);
127
128   return Standard_True;
129 }
130
131 //=======================================================================
132 //function : NewCurve
133 //purpose  : 
134 //=======================================================================
135
136 Standard_Boolean ShapeCustom_DirectModification::NewCurve (const TopoDS_Edge& E,
137                                                            Handle(Geom_Curve)& C,
138                                                            TopLoc_Location& L,
139                                                            Standard_Real& Tol) 
140 {
141   //:p5 abv 26 Feb 99: force copying of edge if any its pcurve will be replaced
142   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
143
144   // iterate on pcurves
145   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
146   for ( ; itcr.More(); itcr.Next() ) {
147     Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
148     if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
149     Handle(Geom_Surface) S = GC->Surface();
150     TopLoc_Location Loc = GC->Location();
151     if ( ! IsIndirectSurface ( S, Loc ) ) continue;
152     Standard_Real f, l;
153     C = BRep_Tool::Curve ( E, L, f, l );
154     if ( ! C.IsNull() ) C = Handle(Geom_Curve)::DownCast ( C->Copy() );
155     Tol = BRep_Tool::Tolerance(E);
156     return Standard_True;
157   }
158   return Standard_False;
159 }
160
161 //=======================================================================
162 //function : NewPoint
163 //purpose  : 
164 //=======================================================================
165
166 Standard_Boolean ShapeCustom_DirectModification::NewPoint (const TopoDS_Vertex& /*V*/,
167                                                            gp_Pnt& /*P*/, 
168                                                            Standard_Real& /*Tol*/) 
169 {
170   // 3d points are never modified
171   return Standard_False;
172 }
173
174 //=======================================================================
175 //function : NewCurve2d
176 //purpose  : 
177 //=======================================================================
178
179 Standard_Boolean ShapeCustom_DirectModification::NewCurve2d (const TopoDS_Edge& E,
180                                                              const TopoDS_Face& F,
181                                                              const TopoDS_Edge& NewE,
182                                                              const TopoDS_Face& NewF,
183                                                              Handle(Geom2d_Curve)& C,
184                                                              Standard_Real& Tol) 
185 {
186   TopLoc_Location L;
187   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
188
189   Standard_Integer result = IsIndirectSurface ( S, L );
190   if ( !result && E.IsSame(NewE) ) return Standard_False;
191
192   Standard_Real f, l;
193   C = BRep_Tool::CurveOnSurface( E, F, f, l );
194   Tol = BRep_Tool::Tolerance(E);
195
196   if ( result ) {
197     
198     gp_Trsf2d T;
199
200     switch (result) {
201       case 1: { // Indirect surface
202         // mirror the PCurve about the V axis
203         T.SetMirror(gp::OY2d());
204         C = Handle(Geom2d_Curve)::DownCast(C->Transformed(T));
205         break;
206       }
207       case 2: { // Negative cone
208         // mirror the PCurve about the U and V axis
209         T.SetMirror(gp::OX2d());
210         C = Handle(Geom2d_Curve)::DownCast(C->Transformed(T));
211         T.SetMirror(gp::OY2d());
212         C->Transform(T);
213         break;
214       }
215       case 3: { // Indirect negative cone
216         // mirror the PCurve about the U axis
217         T.SetMirror(gp::OX2d());
218         C = Handle(Geom2d_Curve)::DownCast(C->Transformed(T));
219         break;
220       }
221     }
222
223     //#26 rln When seam edge contains triangulations trimming is lost by BRep_Builder::UpdateEdge
224     if (BRepTools::IsReallyClosed (E, F)) {
225       //szv#4:S4163:12Mar99 SGI warning
226       TopoDS_Shape sh = NewE.Reversed();
227       Handle(Geom2d_Curve) tmp = BRep_Tool::CurveOnSurface( TopoDS::Edge(sh), NewF, f, l );
228       if (tmp.IsNull()) {
229         tmp = BRep_Tool::CurveOnSurface (E, F, f, l);
230         BRep_Builder B;
231         B.UpdateEdge (NewE, tmp, C, NewF, Tol);
232         B.Range (NewE, NewF, f, l);
233         //anyway, tmp will be removed later by BRepTools_Modifier
234       }
235     }
236   }
237   else {
238     //:p5 abv 26 Feb 99: force copying of pcurves if edge was copied
239     if ( ! C.IsNull() ) C = Handle(Geom2d_Curve)::DownCast ( C->Copy() );
240   }
241
242   return Standard_True;
243 }
244
245 //=======================================================================
246 //function : NewParameter
247 //purpose  : 
248 //=======================================================================
249
250 Standard_Boolean ShapeCustom_DirectModification::NewParameter (const TopoDS_Vertex& /*V*/,
251                                                                const TopoDS_Edge& /*E*/,
252                                                                Standard_Real& /*P*/,
253                                                                Standard_Real& /*Tol*/) 
254 {
255   return Standard_False;
256 }
257
258 //=======================================================================
259 //function : Continuity
260 //purpose  : 
261 //=======================================================================
262
263 GeomAbs_Shape ShapeCustom_DirectModification::Continuity (const TopoDS_Edge& E,
264                                                           const TopoDS_Face& F1,
265                                                           const TopoDS_Face& F2,
266                                                           const TopoDS_Edge& /*NewE*/,
267                                                           const TopoDS_Face& /*NewF1*/,
268                                                           const TopoDS_Face& /*NewF2*/) 
269 {
270   return BRep_Tool::Continuity(E,F1,F2);
271 }