0026106: BRepMesh - revision of data model
[occt.git] / src / BRepMesh / BRepMesh_EdgeParameterProvider.hxx
1 // Created on: 2014-08-13
2 // Created by: Oleg AGASHIN
3 // Copyright (c) 2011-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 #ifndef _BRepMesh_EdgeParameterProvider_HeaderFile
17 #define _BRepMesh_EdgeParameterProvider_HeaderFile
18
19 #include <IMeshData_Types.hxx>
20 #include <IMeshData_Edge.hxx>
21 #include <IMeshData_Face.hxx>
22 #include <TopoDS.hxx>
23 #include <Standard.hxx>
24 #include <Standard_DefineAlloc.hxx>
25 #include <Extrema_LocateExtPC.hxx>
26 #include <TColStd_HArray1OfReal.hxx>
27 #include <BRepAdaptor_Curve.hxx>
28 #include <Adaptor3d_CurveOnSurface.hxx>
29 #include <TColStd_HArray1OfReal.hxx>
30 #include <Geom2dAdaptor_HCurve.hxx>
31 #include <GeomAdaptor_HSurface.hxx>
32
33 class gp_Pnt;
34 class TopoDS_Edge;
35 class TopoDS_Face;
36
37 //! Auxiliary class provides correct parameters 
38 //! on curve regarding SameParameter flag.
39 template<class ParametersCollection>
40 class BRepMesh_EdgeParameterProvider : public Standard_Transient
41 {
42 public:
43
44   DEFINE_STANDARD_ALLOC
45
46   //! Constructor. Initializes empty provider.
47   BRepMesh_EdgeParameterProvider()
48   {
49   }
50
51   //! Constructor.
52   //! @param theEdge edge which parameters should be processed.
53   //! @param theFace face the parametric values are defined for.
54   //! @param theParameters parameters corresponded to discretization points.
55   BRepMesh_EdgeParameterProvider(
56     const IMeshData::IEdgeHandle& theEdge,
57     const TopAbs_Orientation      theOrientation,
58     const IMeshData::IFaceHandle& theFace,
59     const ParametersCollection&   theParameters)
60   {
61     Init(theEdge, theOrientation, theFace, theParameters);
62   }
63
64   //! Initialized provider by the given data.
65   void Init (
66     const IMeshData::IEdgeHandle& theEdge,
67     const TopAbs_Orientation      theOrientation,
68     const IMeshData::IFaceHandle& theFace,
69     const ParametersCollection&   theParameters)
70   {
71     myParameters  = theParameters;
72     myIsSameParam = theEdge->GetSameParam();
73     myScale = 1.;
74
75     // Extract actual parametric values
76     const TopoDS_Edge aEdge = TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation));
77
78     myCurveAdaptor.Initialize(aEdge, theFace->GetFace());
79     if (myIsSameParam)
80     {
81       return;
82     }
83
84     myFirstParam = myCurveAdaptor.FirstParameter();
85     const Standard_Real aLastParam = myCurveAdaptor.LastParameter();
86
87     myFoundParam = myCurParam = myFirstParam;
88
89     // Extract parameters stored in polygon
90     myOldFirstParam                   = myParameters->Value(myParameters->Lower());
91     const Standard_Real aOldLastParam = myParameters->Value(myParameters->Upper());
92
93     // Calculate scale factor between actual and stored parameters
94     if ((myOldFirstParam != myFirstParam || aOldLastParam != aLastParam) &&
95         myOldFirstParam != aOldLastParam)
96     {
97       myScale = (aLastParam - myFirstParam) / (aOldLastParam - myOldFirstParam);
98     }
99
100     myProjector.Initialize(myCurveAdaptor, myCurveAdaptor.FirstParameter(), 
101                            myCurveAdaptor.LastParameter(),Precision::PConfusion());
102   }
103
104   //! Returns parameter according to SameParameter flag of the edge.
105   //! If SameParameter is TRUE returns value from parameters w/o changes,
106   //! elsewhere scales initial parameter and tries to determine resulting
107   //! value using projection of the corresponded 3D point on PCurve.
108   Standard_Real Parameter(const Standard_Integer theIndex,
109                           const gp_Pnt&          thePoint3d) const
110   {
111     if (myIsSameParam)
112     {
113       return myParameters->Value(theIndex);
114     }
115
116     // Use scaled
117     const Standard_Real aParam = myParameters->Value(theIndex);
118
119     const Standard_Real aPrevParam = myCurParam;
120     myCurParam = myFirstParam + myScale * (aParam - myOldFirstParam);
121
122     const Standard_Real aPrevFoundParam = myFoundParam;
123     myFoundParam += (myCurParam - aPrevParam);
124
125     myProjector.Perform(thePoint3d, myFoundParam);
126     if (myProjector.IsDone())
127     {
128       const Standard_Real aFoundParam = myProjector.Point().Parameter();
129       if ((aPrevFoundParam < myFoundParam && aPrevFoundParam < aFoundParam) ||
130           (aPrevFoundParam > myFoundParam && aPrevFoundParam > aFoundParam))
131       {
132         // Rude protection against case when amplified parameter goes before 
133         // previous one due to period or other reason occurred in projector.
134         // Using parameter returned by projector as is can produce self-intersections.
135         myFoundParam = aFoundParam;
136       }
137     }
138
139     return myFoundParam;
140   }
141
142   //! Returns pcurve used to compute parameters.
143   const Handle(Adaptor2d_HCurve2d)& GetPCurve() const
144   {
145     return myCurveAdaptor.CurveOnSurface().GetCurve();
146   }
147
148 private:
149
150   ParametersCollection          myParameters;
151
152   Standard_Boolean              myIsSameParam;
153   Standard_Real                 myFirstParam;
154
155   Standard_Real                 myOldFirstParam;
156   Standard_Real                 myScale;
157
158   mutable Standard_Real         myCurParam;
159   mutable Standard_Real         myFoundParam;
160
161   BRepAdaptor_Curve             myCurveAdaptor;
162
163   mutable Extrema_LocateExtPC   myProjector;
164 };
165
166 #endif