1 // Created on: 2000-06-07
2 // Created by: Galina KULIKOVA
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15 
16 
17 #include <BRep_Tool.hxx>
18 #include <Geom2d_BSplineCurve.hxx>
19 #include <Geom2d_Curve.hxx>
20 #include <Geom2d_TrimmedCurve.hxx>
21 #include <Geom2dConvert_ApproxCurve.hxx>
22 #include <Geom_BSplineCurve.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <GeomAbs_Shape.hxx>
27 #include <GeomAdaptor_Surface.hxx>
28 #include <GeomConvert_ApproxCurve.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <ShapeAnalysis_Edge.hxx>
32 #include <ShapeExtend.hxx>
33 #include <ShapeUpgrade_FixSmallBezierCurves.hxx>
34 #include <ShapeUpgrade_SplitCurve2d.hxx>
35 #include <ShapeUpgrade_SplitCurve3d.hxx>
36 #include <Standard_ErrorHandler.hxx>
37 #include <Standard_Failure.hxx>
38 #include <Standard_Type.hxx>
39 #include <TColGeom2d_HArray1OfCurve.hxx>
40 #include <TColGeom_HArray1OfCurve.hxx>
41 #include <TopExp.hxx>
42 #include <TopLoc_Location.hxx>
43 #include <TopoDS.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Shape.hxx>
46 
IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_FixSmallBezierCurves,ShapeUpgrade_FixSmallCurves)47 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_FixSmallBezierCurves,ShapeUpgrade_FixSmallCurves)
48 
49 ShapeUpgrade_FixSmallBezierCurves::ShapeUpgrade_FixSmallBezierCurves()
50 {
51 }
52 
Approx(Handle (Geom_Curve)& Curve3d,Handle (Geom2d_Curve)& Curve2d,Handle (Geom2d_Curve)& Curve2dR,Standard_Real & First,Standard_Real & Last)53 Standard_Boolean ShapeUpgrade_FixSmallBezierCurves::Approx(Handle(Geom_Curve)& Curve3d,Handle(Geom2d_Curve)& Curve2d,Handle(Geom2d_Curve)& Curve2dR,Standard_Real& First,Standard_Real& Last)
54 {
55 
56   ShapeAnalysis_Edge sae;
57   Handle(Geom_Curve) c3d;
58   Standard_Real f,l;
59   if(sae.Curve3d(myEdge,c3d,f,l,Standard_False)) {
60     if(First < f)
61       First = f;
62     if(Last > l)
63       Last =l;
64     Handle(Geom_Curve) trc = new  Geom_TrimmedCurve(c3d,First,Last);
65     GeomAbs_Shape aCont = (GeomAbs_Shape)trc->Continuity();
66     if(aCont == GeomAbs_C3 || aCont == GeomAbs_CN)
67       aCont = GeomAbs_C2;
68     try {
69       OCC_CATCH_SIGNALS
70       GeomConvert_ApproxCurve AproxCurve(trc,Precision(),aCont,1,9);
71       if(AproxCurve.IsDone()) {
72 	Handle(Geom_Curve) newCurve = AproxCurve.Curve();
73 	mySplitCurve3dTool->Init(AproxCurve.Curve(),First,Last);
74 	mySplitCurve3dTool->Perform(Standard_True);
75 	if (!mySplitCurve3dTool->Status ( ShapeExtend_FAIL )) {
76 	  Handle(TColGeom_HArray1OfCurve) theSegments3d;
77 	  theSegments3d = mySplitCurve3dTool->GetCurves();
78 	  if(theSegments3d->Length() >1) return Standard_False;
79 	  Curve3d = theSegments3d->Value(1);
80 	}
81       }
82     }
83     catch (Standard_Failure const& anException) {
84 #ifdef OCCT_DEBUG
85       std::cout << "Warning: ShapeUpgrade_FixSmallBezierCurve::Approx(): Exception in Segment      :";
86       anException.Print(std::cout); std::cout << std::endl;
87 #endif
88       (void)anException;
89       return Standard_False;
90     }
91   }
92   if ( myFace.IsNull() ) return Standard_True;
93   Handle(Geom2d_Curve) c2d;
94   TopLoc_Location L;
95   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace,L);
96   GeomAdaptor_Surface ads(aSurf);// = new GeomAdaptor_Surface(aSurf);
97   Standard_Real prec = Max(ads.UResolution(Precision()),ads.VResolution(Precision()));
98   if(sae.PCurve(myEdge,myFace,c2d,f,l,Standard_False)) {
99     if(First < f)
100       First = f;
101     if(Last > l)
102       Last =l;
103     Handle(Geom2d_Curve) trc2d = new  Geom2d_TrimmedCurve(c2d,First,Last);
104     GeomAbs_Shape aCont = (GeomAbs_Shape)trc2d->Continuity();
105     try {
106       OCC_CATCH_SIGNALS
107       Geom2dConvert_ApproxCurve AproxCurve2d(trc2d,prec,aCont,1,9);
108       if(AproxCurve2d.IsDone()) {
109 	Handle(Geom2d_Curve) newCurve = AproxCurve2d.Curve();
110 	mySplitCurve2dTool->Init(AproxCurve2d.Curve(),First,Last);
111 	mySplitCurve2dTool->Perform(Standard_True);
112 	if ( mySplitCurve2dTool->Status ( ShapeExtend_FAIL ))
113 	  return Standard_False;
114 	Handle(TColGeom2d_HArray1OfCurve) theSegments2d;
115 	theSegments2d = mySplitCurve2dTool->GetCurves();
116 	if(theSegments2d->Length() >1) return Standard_False; //ShapeAnalysis_Surface
117 	Curve2d = theSegments2d->Value(1);
118       }
119     }
120     catch (Standard_Failure const& anException) {
121 #ifdef OCCT_DEBUG
122       std::cout << "Warning: ShapeUpgrade_FixSmallBezierCurve::Approx(): Exception in Segment      :";
123       anException.Print(std::cout); std::cout << std::endl;
124 #endif
125       (void)anException;
126       return Standard_False;
127     }
128   }
129   Standard_Boolean isSeam = BRep_Tool::IsClosed ( myEdge, myFace );
130   if ( isSeam ) {
131     Handle(Geom2d_Curve) c2;
132     Standard_Real f2, l2;
133     //smh#8
134     TopoDS_Shape tmpE = myEdge.Reversed();
135     TopoDS_Edge erev = TopoDS::Edge (tmpE );
136     if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) {
137       if(First > f)
138 	First = f;
139       if(Last > l)
140 	Last =l;
141       Handle(Geom2d_Curve) trc2d = new  Geom2d_TrimmedCurve(c2,First,Last);
142       GeomAbs_Shape aCont = trc2d->Continuity();
143       Geom2dConvert_ApproxCurve AproxCurve2d(trc2d,prec,aCont,1,9);
144       try {
145         OCC_CATCH_SIGNALS
146 	if(AproxCurve2d.IsDone()) {
147 	  Handle(Geom2d_Curve) newCurve = AproxCurve2d.Curve();
148 	  mySplitCurve2dTool->Init(AproxCurve2d.Curve(),First,Last);
149 	  mySplitCurve2dTool->Perform(Standard_True);
150 	  if ( ! mySplitCurve2dTool->Status ( ShapeExtend_DONE ))
151 	    return Standard_False;
152 	  Handle(TColGeom2d_HArray1OfCurve) theSegments2d;
153 	  theSegments2d = mySplitCurve2dTool->GetCurves();
154 	  if(theSegments2d->Length() >1) return Standard_False; //ShapeAnalysis_Surface
155 	  Curve2dR = theSegments2d->Value(1);
156 	}
157       }
158       catch (Standard_Failure const& anException) {
159 #ifdef OCCT_DEBUG
160 	  std::cout << "Warning: ShapeUpgrade_FixSmallBezierCurve::Approx(): Exception in Segment      :";
161 	  anException.Print(std::cout); std::cout << std::endl;
162 #endif
163 	  (void)anException;
164 	  return Standard_False;
165 	}
166     }
167   }
168   return Standard_True;
169 }
170 
171