1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-08 14:17:06 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
nbv
c7d505061e 0025029: GeomFill_Pipe does not respect first and last parameters of the path
Documentation has been updated in accordance with the request.
2015-06-04 09:50:47 +03:00
407 changed files with 5018 additions and 12395 deletions

View File

@@ -2366,6 +2366,12 @@ The shape defining the construction of a feature can be either a supporting edge
In case of supporting edge, this contour can be attached to a face of the basis shape by binding. When the contour is bound to this face, the information that the contour will slide on the face becomes available
to the relevant class methods. In case of the concerned area of a face, you can, for example, cut it out and move it at a different height, which defines the limiting face of a protrusion or depression.
Briefly, the algorithm can be described as follows:
1. For every profile (several profiles are supported too) a corresponding parameter on the path is found. For definition this parameter (in case when the profile is not planar), the profile is approximated by a plane (location is barycenter of the profile, normal is its upper axe of inertia). If the profile is segment of some line (approximation problem has infinite solution) the position on the path will coincide with the nearest point to the profile (which is found by Curve-Curve-Extrema algorithm).
1. If this plane intersect the path then result will cover given path fully. It is recommended for good work of the algorithm.
2. Otherwise (when condition in item "a" is not satisfied) the feature will be made from intersection point the plane and the path. In most cases this result is unexpected. Therefore, if it is necessary, you can use special options for translating the profile in order to provide its contact with the path.
2. The profile is created in every point of the path. This profile is obtained from the source profiles with some translation. The translation is defined by Frenet's trihedron (tangent, normal and bi-normal).
Topological definition with local operations of this sort makes calculations simpler
and faster than a global operation. The latter would entail a second phase
of removing unwanted matter to get the same result.

View File

@@ -780,7 +780,7 @@ TopoDS_Face F = BRepBuilderAPI_MakeFace(gp_Pln(gp::XOY()),Wc); \n\
axe = gp_Ax1(gp_Pnt(290,290.,0.),gp_Dir(0.,1,0.)); \n\
TopoDS_Shape S4 = BRepPrimAPI_MakeRevol(F,axe, 90.*PI180); \n\
\n");
PocessTextInDialog("Make a revol", Message);
PocessTextInDialog("Make a prism", Message);
}
void CModelingDoc::OnPipe()

View File

@@ -115,8 +115,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;FWOSPlugin.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc11\bind/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc11\libd/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB32D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -158,8 +163,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;FWOSPlugin.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc11\bind/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc11\libd/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB64D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -202,8 +212,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc11\bin/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc11\lib/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB32);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>../../../../win32\vc11\bin/mfcsample.pdb</ProgramDatabaseFile>
@@ -246,8 +261,13 @@
<ResourceOutputFileName>$(IntDir)%(Filename).res</ResourceOutputFileName>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc11\bin/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc11\lib/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>../../../../win64\vc11\bin/mfcsample.pdb</ProgramDatabaseFile>

View File

@@ -115,8 +115,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;FWOSPlugin.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc12\bind/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc12\libd/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB32D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -158,8 +163,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;FWOSPlugin.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc12\bind/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;FWOSPlugin.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc12\libd/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB64D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -202,8 +212,13 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc12\bin/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\vc12\lib/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB32);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>../../../../win32\vc12\bin/mfcsample.pdb</ProgramDatabaseFile>
@@ -246,8 +261,13 @@
<ResourceOutputFileName>$(IntDir)%(Filename).res</ResourceOutputFileName>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<<<<<<< HEAD
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKShapeSchema.lib;PTKernel.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPCAF.lib;TKPrim.lib;TKPShape.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc12\bin/mfcsample.dll</OutputFile>
=======
<AdditionalDependencies>TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\vc12\lib/mfcsample.dll</OutputFile>
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OPT_LIB64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>../../../../win64\vc12\bin/mfcsample.pdb</ProgramDatabaseFile>

View File

@@ -80,8 +80,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib FWOSPlugin.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc8\bind/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc8\libd/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB32D)"
@@ -179,8 +184,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc8\bin/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc8\lib/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB32)"
@@ -276,8 +286,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib FWOSPlugin.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc8\bind/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc8\libd/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB64D)"
@@ -375,8 +390,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc8\bin/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc8\lib/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB64)"

View File

@@ -81,8 +81,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib FWOSPlugin.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc9\bind/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc9\libd/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB32D)"
@@ -178,8 +183,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib FWOSPlugin.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc9\bind/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib FWOSPlugin.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc9\libd/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB64D)"
@@ -276,8 +286,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc9\bin/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win32\vc9\lib/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB32)"
@@ -373,8 +388,13 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
<<<<<<< HEAD
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKShapeSchema.lib PTKernel.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPCAF.lib TKPrim.lib TKPShape.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc9\bin/mfcsample.dll"
=======
AdditionalDependencies="TKVrml.lib TKStl.lib TKBrep.lib TKIGES.lib TKShHealing.lib TKStep.lib TKXSBase.lib TKBool.lib TKCAF.lib TKCDF.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKMath.lib TKOffset.lib TKPrim.lib TKService.lib TKTopAlgo.lib TKMesh.lib TKV3d.lib TKOpenGl.lib"
OutputFile="../../../../win64\vc9\lib/mfcsample.dll"
>>>>>>> 9479c49... 0024927: Getting rid of "Persistent" functionality -- Samples and data
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(CSF_OPT_LIB64)"

View File

@@ -195,11 +195,11 @@
<translation>STEP Files (*.stp *.step)</translation>
</message>
<message>
<source>INF_FILTER_FORMAT_3</source>
<source>INF_FILTER_FORMAT_4</source>
<translation>VRML Files (*.vrml)</translation>
</message>
<message>
<source>INF_FILTER_FORMAT_4</source>
<source>INF_FILTER_FORMAT_5</source>
<translation>STL Files (*.stl)</translation>
</message>
</context>

View File

@@ -1,12 +1,10 @@
# Creation of 2d drawing
#Category: Modeling
#Title: Snowflake - creation of 2d drawing
#Category: Modeling
#Title: Snowflake - creation of 2d geometry
pload MODELING AISV
puts "Generating sample drawing of snowflake..."
# make circular elements
circle c11 5 5 0 5
circle c12 5 5 0 3
@@ -123,22 +121,10 @@ eval compound [explode scale w] scale
eval compound [explode mass w] mass
compound sample occ name material sheets scale mass text
compound snowflake lines text drawing
compound snowflake frame text drawing
# display in 3d view
vinit Driver1/Viewer1/View1 w=1024 h=768
vdisplay snowflake lines text
vsetcolor snowflake 0 0 0
vsetcolor lines 0 0 0
vsetcolor text 0 0 0
vsetcolorbg 255 255 255
vtop
vfit
# add dimension
explode snowflake v
vdimension length -length -shapes snowflake_93 snowflake_15 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
if { [regexp HAVE_GL2PS [dversion]] } {
puts "You can use command vexport to generate PDF: vexport your_file_path.pdf"
}
vfit

View File

@@ -2333,16 +2333,9 @@ void AIS_InteractiveContext::EraseGlobal (const Handle(AIS_InteractiveObject)& t
for (TColStd_ListIteratorOfListOfInteger aDispModeIter (aStatus->DisplayedModes()); aDispModeIter.More(); aDispModeIter.Next())
{
if (aStatus->IsHilighted())
if (myMainPM->IsHighlighted (theIObj, aDispModeIter.Value()))
{
if (IsCurrent (theIObj))
{
AddOrRemoveCurrentObject (theIObj, Standard_False);
}
else if (myMainPM->IsHighlighted (theIObj, aDispModeIter.Value()))
{
myMainPM->Unhighlight (theIObj, aDispModeIter.Value());
}
myMainPM->Unhighlight (theIObj, aDispModeIter.Value());
}
myMainPM->SetVisibility (theIObj, aDispModeIter.Value(), Standard_False);

View File

@@ -454,7 +454,7 @@ is
-- - Pewter
-- - Silver
-- - Stone.
SetMaterial(me:mutable;aName:NameOfMaterial from Graphic3d) is virtual;
---Purpose: Sets the name aName for material defining this
-- display attribute for the interactive object.

View File

@@ -276,7 +276,9 @@ void AIS_InteractiveObject::UnsetWidth()
//function :
//purpose :
//=======================================================================
//POP pour K4L
void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
//void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
{
if( HasColor() || IsTransparent() || HasMaterial() )
{
@@ -290,57 +292,44 @@ void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
myOwnMaterial = aName;
hasOwnMaterial = Standard_True;
}
//=======================================================================
//function : SetMaterial
//purpose :
//=======================================================================
void AIS_InteractiveObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
{
if (!HasColor() && !IsTransparent() && !HasMaterial())
if (HasColor() || IsTransparent() || HasMaterial())
{
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect);
myDrawer->ShadingAspect()->SetMaterial(aMat);
}
else
{
myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
myDrawer->ShadingAspect()->SetMaterial(aMat);
}
myDrawer->ShadingAspect()->SetMaterial (theMaterial);
hasOwnMaterial = Standard_True;
}
//=======================================================================
//function : UnsetMaterial
//purpose :
//function :
//purpose :
//=======================================================================
void AIS_InteractiveObject::UnsetMaterial()
{
if (!HasMaterial())
{
return;
}
if( !HasMaterial() ) return;
if (HasColor() || IsTransparent())
{
if(myDrawer->HasLink())
{
myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
}
if (HasColor())
{
SetColor (myOwnColor);
}
if (IsTransparent())
{
SetTransparency (myTransparency);
}
if (HasColor()) SetColor (myOwnColor);
if (IsTransparent()) SetTransparency (myTransparency);
}
else
{
Handle(Prs3d_ShadingAspect) anAspect;
myDrawer->SetShadingAspect (anAspect);
else{
Handle(Prs3d_ShadingAspect) SA;
myDrawer->SetShadingAspect(SA);
}
hasOwnMaterial = Standard_False;
}

View File

@@ -1454,10 +1454,8 @@ Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const
Standard_Boolean found(Standard_False);
if (!found) {
NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
myMainVS->ActiveOwners (anActiveOwners);
for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
{
NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (myMainVS->ActiveOwners());
for (; anOwnersIt.More(); anOwnersIt.Next()) {
EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {

View File

@@ -14,7 +14,6 @@
#include <Standard_NotImplemented.hxx>
#include <Adaptor3d_TopolTool.ixx>
#include <Precision.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <gp_Cone.hxx>
#include <gp_Pnt.hxx>
@@ -1081,10 +1080,6 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
Standard_Integer l;
// Calculations of B-spline values will be made using adaptor,
// because it caches the data for performance
GeomAdaptor_Surface aBSplAdaptor(aBS);
anUFlg(1) = Standard_True;
anUFlg(nbsu) = Standard_True;
//myNbSamplesU = 2;
@@ -1100,12 +1095,10 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
}
t2 = anUPars(j);
// gp_Pnt p1 = aBS->Value(t2, t1);
gp_Pnt p1 = aBSplAdaptor.Value(t2, t1);
gp_Pnt p1 = aBS->Value(t2, t1);
for(k = j+2; k <= nbsu; ++k) {
t2 = anUPars(k);
// gp_Pnt p2 = aBS->Value(t2, t1);
gp_Pnt p2 = aBSplAdaptor.Value(t2, t1);
gp_Pnt p2 = aBS->Value(t2, t1);
//gce_MakeLin MkLin(p1, p2);
//const gp_Lin& lin = MkLin.Value();
@@ -1120,8 +1113,7 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break;
}
// gp_Pnt pp = aBS->Value(anUPars(l), t1);
gp_Pnt pp = aBSplAdaptor.Value(anUPars(l), t1);
gp_Pnt pp = aBS->Value(anUPars(l), t1);
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;
@@ -1188,12 +1180,10 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
}
t2 = aVPars(j);
// gp_Pnt p1 = aBS->Value(t1, t2);
gp_Pnt p1 = aBSplAdaptor.Value(t1, t2);
gp_Pnt p1 = aBS->Value(t1, t2);
for(k = j+2; k <= nbsv; ++k) {
t2 = aVPars(k);
// gp_Pnt p2 = aBS->Value(t1, t2);
gp_Pnt p2 = aBSplAdaptor.Value(t1, t2);
gp_Pnt p2 = aBS->Value(t1, t2);
if(p1.SquareDistance(p2) <= tol) continue;
//gce_MakeLin MkLin(p1, p2);
@@ -1207,8 +1197,7 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break;
}
// gp_Pnt pp = aBS->Value(t1, aVPars(l));
gp_Pnt pp = aBSplAdaptor.Value(t1, aVPars(l));
gp_Pnt pp = aBS->Value(t1, aVPars(l));
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;

View File

@@ -385,7 +385,7 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
Standard_Real Tol = Tolerance;
Standard_Real Tol2 = Tol * Tol;
Standard_Real deltamin = Precision::PConfusion();//50*Tolp;
Standard_Real Tolp = myC3d->Resolution(Tol), deltamin = 50*Tolp;
Standard_Real besttol2 = Tol2;
Standard_Boolean extrok = 0;
@@ -414,7 +414,7 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
else extrok = 0;
//if(dmax2 > besttol2) besttol2 = dmax2;
if(dmax2 > besttol2) besttol2 = dmax2;
//Take a multiple of the sample pof CheckShape,
//at least the control points will be correct. No comment!!!
@@ -507,14 +507,12 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
myC3d->D0(pc3d[ii],Pc3d);
dist2 = Pcons.SquareDistance(Pc3d);
use_parameter = (dist2 <= Tol2 && (pc3d[ii] > pc3d[count-1] + deltamin)) ;
Standard_Real aDistMin = RealLast();;
if(use_parameter) {
if(dist2 > dmax2) dmax2 = dist2;
initp = previousp = pc3d[count] = pc3d[ii];
pcons[count] = pcons[ii];
count++;
}
else {
if(!projok) initp = pc3d[ii];
@@ -523,25 +521,21 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
if (Projector.IsDone()) {
curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance();
projok = Standard_True;
aDistMin = dist_2;
if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1;
}
else
{
ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp);
if(projok)
{
const gp_Pnt& ap1 =myC3d->Value(curp);
aDistMin = Pcons.SquareDistance(ap1);
}
}
projok = (projok && (curp > previousp + deltamin && curp < bornesup));
if(projok)
{
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
if(curp > previousp + deltamin && curp < bornesup){
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
}
}
else
{
@@ -552,38 +546,30 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
if(aNbExt > 0)
{
Standard_Integer anIndMin = 0;
Standard_Real aCurDistMin = RealLast();
Standard_Real aDistMin = RealLast();
for(Standard_Integer i = 1; i <= aNbExt; i++)
{
const gp_Pnt &aP = PR.Point(i).Value();
Standard_Real aDist2 = aP.SquareDistance(Pcons);
if(aDist2 < aCurDistMin)
if(aDist2 < aDistMin)
{
aCurDistMin = aDist2;
aDistMin = aDist2;
anIndMin = i;
}
}
if(anIndMin)
curp = PR.Point(anIndMin).Parameter();
if(curp > previousp + deltamin && curp < bornesup)
{
curp = PR.Point(anIndMin).Parameter();
if( curp > previousp + deltamin && curp < bornesup)
{
aDistMin = aCurDistMin;
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
projok = Standard_True;
}
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
projok = Standard_True;
}
}
}
}
if(projok && besttol2 < aDistMin)
besttol2 = aDistMin;
else if(!projok)
if(!projok)
{
//Projector
#ifdef OCCT_DEBUG

View File

@@ -43,8 +43,7 @@ static
TopoDS_Shell& );
//
static
void RefineShell(TopoDS_Shell& theShell,
BOPCol_ListOfShape& aLShX);
void RefineShell(TopoDS_Shell& theShell);
//
static
void MapEdgesAndFaces
@@ -330,9 +329,8 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
BOPTools_CoupleOfShape aCSOff;
BOPCol_MapOfOrientedShape AddedFacesMap;
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
Handle (IntTools_Context) aContext;
//
aContext=new IntTools_Context;
Handle (IntTools_Context) aContext=new IntTools_Context;
//
const BOPCol_ListOfShape& myShapes=aCB.Shapes();
//
@@ -347,7 +345,6 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
TopAbs_EDGE,
TopAbs_FACE,
aEFMap);
}
//
aItF.Initialize (myShapes);
@@ -457,18 +454,15 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
} // for (; aExp.More(); aExp.Next()) {
} // for (; aItS.More(); aItS.Next()) {
//
BOPCol_ListOfShape aLShX;
BOPCol_ListIteratorOfListOfShape aItLShX;
//
RefineShell(aShell, aLShX);
//
aItLShX.Initialize(aLShX);
for (; aItLShX.More(); aItLShX.Next()) {
TopoDS_Shell& aShX=*((TopoDS_Shell*)&aItLShX.Value());
//
if (BRep_Tool::IsClosed(aShX)) {
aShX.Closed(Standard_True);
myLoops.Append(aShX);
if (BRep_Tool::IsClosed(aShell)) {
aShell.Closed (Standard_True);
myLoops.Append(aShell);
}
else {
RefineShell(aShell);
if (BRep_Tool::IsClosed(aShell)) {
aShell.Closed (Standard_True);
myLoops.Append(aShell);
}
}
} // for (; aItF.More(); aItF.Next()) {
@@ -477,8 +471,7 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
//function : RefineShell
//purpose :
//=======================================================================
void RefineShell(TopoDS_Shell& theShell,
BOPCol_ListOfShape& aLShX)
void RefineShell(TopoDS_Shell& theShell)
{
TopoDS_Iterator aIt;
//
@@ -487,12 +480,12 @@ void RefineShell(TopoDS_Shell& theShell,
return;
}
//
Standard_Integer i, aNbMEF, aNbF, aNbMFB;
Standard_Integer i, aNbMEF, aNbF;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
TopoDS_Builder aBB;
TopExp_Explorer aExp;
BOPCol_IndexedMapOfShape aMFB;
BOPCol_MapOfShape aMEStop, aMFProcessed;
BOPCol_MapOfShape aMEStop, aMFB;
BOPCol_MapIteratorOfMapOfShape aItM;
BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
BOPCol_ListOfShape aLFP, aLFP1;
//
@@ -501,7 +494,6 @@ void RefineShell(TopoDS_Shell& theShell,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
aNbMEF=aMEF.Extent();
for (i=1; i<=aNbMEF; ++i) {
const TopoDS_Shape& aE=aMEF.FindKey(i);
@@ -513,86 +505,69 @@ void RefineShell(TopoDS_Shell& theShell,
}
//
if (aMEStop.IsEmpty()) {
aLShX.Append(theShell);
return;
}
//
// The first Face
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF1=aIt.Value();
if (!aMFProcessed.Add(aF1)) {
continue;
}
//
aMFB.Clear();
aLFP.Clear();
//
aMFB.Add(aF1);
aLFP.Append(aF1);
//
// Trying to reach the branch point
for (;;) {
aItLFP.Initialize(aLFP);
for (; aItLFP.More(); aItLFP.Next()) {
const TopoDS_Shape& aFP=aItLFP.Value();
const TopoDS_Shape& aF1=aIt.Value();
aMFB.Add(aF1);
aLFP.Append(aF1);
//
// Trying to reach the branch point
for (;;) {
aItLFP.Initialize(aLFP);
for (; aItLFP.More(); aItLFP.Next()) {
const TopoDS_Shape& aFP=aItLFP.Value();
//
aExp.Init(aFP, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (aMEStop.Contains(aE)) {
continue;
}
//
aExp.Init(aFP, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (aMEStop.Contains(aE)) {
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
if (aFP1.IsSame(aFP)) {
continue;
}
//
if (BRep_Tool::Degenerated(aE)) {
if (aMFB.Contains(aFP1)) {
continue;
}
//
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
if (aFP1.IsSame(aFP)) {
continue;
}
if (aMFB.Contains(aFP1)) {
continue;
}
//
aMFProcessed.Add(aFP1);
aMFB.Add(aFP1);
aLFP1.Append(aFP1);
}// for (; aItLF.More(); aItLF.Next()) {
}// for (; aExp.More(); aExp.Next()) {
} // for (; aItLFP.More(); aItLFP.Next()) {
//
//
if (aLFP1.IsEmpty()) {
break;
}
//
aLFP.Clear();
aItLF.Initialize(aLFP1);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
aLFP.Append(aFP1);
}
aLFP1.Clear();
}// for (;;) {
aMFB.Add(aFP1);
aLFP1.Append(aFP1);
}// for (; aItLF.More(); aItLF.Next()) {
}// for (; aExp.More(); aExp.Next()) {
}// for (; aItLFP.More(); aItLFP.Next()) {
//
aNbMFB=aMFB.Extent();
if (aNbMFB) {
TopoDS_Shell aShX;
aBB.MakeShell(aShX);
//
for (i=1; i<=aNbMFB; ++i) {
const TopoDS_Shape& aFB=aMFB(i);
aBB.Add(aShX, aFB);
}
aLShX.Append(aShX);
//
if (aLFP1.IsEmpty()) {
break;
}
}//for (; aIt.More(); aIt.Next()) {
}
//
aLFP.Clear();
aItLF.Initialize(aLFP1);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
aLFP.Append(aFP1);
}
aLFP1.Clear();
}// for (;;) {
//
// Remove all faces before the branch point
aItM.Initialize(aMFB);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFB=aItM.Value();
aBB.Remove(theShell, aFB);
}
}
//=======================================================================
//function : MakeShells
//purpose :

View File

@@ -762,8 +762,8 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
aTV1=aTV - dt;
}
//
aGAC2D.D0 (aTV1, aPV1);
aGAC2D.D0 (aTV, aPV);
aC2D->D0 (aTV1, aPV1);
aC2D->D0 (aTV, aPV);
//
aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
//
@@ -1017,15 +1017,15 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
aTolInt=1.e-10;
//
BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol);
aGAC1.Load(aC2D, aT1, aT2);
//
aTV=BRep_Tool::Parameter (aV, aE, myFace);
aGAC1.D0(aTV, aPV);
aC2D->D0(aTV, aPV);
//
aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
//
aGAC1.D0(aT1, aP1);
aGAC1.D0(aT2, aP2);
aGAC1.Load(aC2D, aT1, aT2);
aC2D->D0(aT1, aP1);
aC2D->D0(aT2, aP2);
aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
//
for (i=0; i<2; ++i) {
@@ -1066,7 +1066,7 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
}
//
aT=aT1max + aCf*dT;
aGAC1.D0(aT, aP);
aC2D->D0(aT, aP);
gp_Vec2d aV2D(aPV, aP);
gp_Dir2d aDir2D(aV2D);
//

View File

@@ -678,8 +678,8 @@ Standard_Integer bopcurves (Draw_Interpretor& di,
//
anIsDone=aFF.IsDone();
if (!anIsDone) {
di << "Error: anIsDone=" << (Standard_Integer) anIsDone << "\n";
return 0;
di << " anIsDone=" << (Standard_Integer) anIsDone << "\n";
return 1;
}
//
aFF.PrepareLines3D(Standard_False);
@@ -692,7 +692,7 @@ Standard_Integer bopcurves (Draw_Interpretor& di,
aNbCurves=aSCs.Length();
if (!aNbCurves) {
di << " has no 3d curve\n";
return 0;
return 1;
}
else
{

View File

@@ -999,7 +999,7 @@ Standard_Integer checkcurveonsurf(Draw_Interpretor& di,
}
//
aTolE = BRep_Tool::Tolerance(aE);
if (!(aDMax > aTolE)) {
if (aDMax < aTolE) {
continue;
}
//

View File

@@ -1281,10 +1281,10 @@ Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
dU=-dU;
}
//
aBAC2D.D0(aU, aP2D0);
aC2D->D0(aU, aP2D0);
for(i=2; i<=aNbS; i++) {
aU=aU1+(i-1)*dU;
aBAC2D.D0(aU, aP2D1);
aC2D->D0(aU, aP2D1);
aP2D0.Coord(aX0, aY0);
aP2D1.Coord(aX1, aY1);
//

View File

@@ -38,8 +38,7 @@ is
aF: Face from TopoDS);
---Purpose:
--- Compute P-Curve for the edge <aE> on the face <aF>
--- Raises exception Standard_ConstructionError if projection algorithm fails
---
EdgeTangent (myclass;
anE : Edge from TopoDS;
aT : Real from Standard;
@@ -57,11 +56,8 @@ is
V : out Real from Standard);
---Purpose:
--- Compute surface parameters <U,V> of the face <aF>
--- for the point from the edge <aE> at parameter <aT>.
--- If <aE> has't pcurve on surface, algorithm tries to get it by
--- projection and can
--- raise exception Standard_ConstructionError if projection algorithm fails
--- for the point from the edge <aE> at parameter <aT>.
---
CurveOnSurface (myclass;
aE: Edge from TopoDS;
aF: Face from TopoDS;
@@ -71,8 +67,7 @@ is
--- Get P-Curve <aC> for the edge <aE> on surface <aF> .
--- If the P-Curve does not exist, build it using Make2D().
--- [aToler] - reached tolerance
--- Raises exception Standard_ConstructionError if algorithm Make2D() fails
---
CurveOnSurface (myclass;
aE: Edge from TopoDS;
aF: Face from TopoDS;
@@ -86,8 +81,7 @@ is
--- If the P-Curve does not exist, build it using Make2D().
--- [aFirst, aLast] - range of the P-Curve
--- [aToler] - reached tolerance
--- Raises exception Standard_ConstructionError if algorithm Make2D() fails
---
HasCurveOnSurface (myclass;
aE: Edge from TopoDS;
aF: Face from TopoDS;
@@ -173,8 +167,18 @@ is
--- Make P-Curve <aC> for the edge <aE> on surface <aF> .
--- [aFirst, aLast] - range of the P-Curve
--- [aToler] - reached tolerance
--- Raises exception Standard_ConstructionError if algorithm fails
---
MakeCurveOnSurface (myclass;
aE: Edge from TopoDS;
aF: Face from TopoDS;
aC : out Curve from Geom2d;
aFirst: out Real from Standard;
aLast : out Real from Standard;
aToler: out Real from Standard);
---Purpose:
--- Same as Make2D()
---
MakePCurveOnFace (myclass;
aF: Face from TopoDS;
C3D : Curve from Geom;
@@ -183,8 +187,7 @@ is
---Purpose:
--- Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .
--- [aToler] - reached tolerance
--- Raises exception Standard_ConstructionError if projection algorithm fails
---
MakePCurveOnFace (myclass;
aF: Face from TopoDS;
C3D : Curve from Geom;
@@ -196,8 +199,7 @@ is
--- Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .
--- [aT1, aT2] - range to build
--- [aToler] - reached tolerance
--- Raises exception Standard_ConstructionError if projection algorithm fails
---
MakePCurveOfType (myclass;
PC : ProjectedCurve from ProjLib;
aC : out Curve from Geom2d);

View File

@@ -15,7 +15,6 @@
#include <BOPTools_AlgoTools2D.ixx>
#include <Standard_NotImplemented.hxx>
#include <Standard_ConstructionError.hxx>
#include <Precision.hxx>
#include <gp.hxx>
@@ -653,12 +652,6 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
aTolR = aProj3.GetTolerance();
}
}
//
if(aC2D.IsNull())
{
Standard_ConstructionError::Raise("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null");
}
//
TolReached2d=aTolR;
BOPTools_AlgoTools2D::AdjustPCurveOnFace (aBAS, aT1, aT2,
aC2D, aC2DA);

View File

@@ -111,7 +111,7 @@ static
static
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
const GeomAdaptor_Surface& aS,
const Handle(Geom_Surface)& aS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2);
@@ -558,7 +558,7 @@ void CorrectWires(const TopoDS_Face& aFx)
aT=BRep_Tool::Parameter(aV, aE);
//
aC2D->D0(aT, aP2D);
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aS->D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) {
aD2max=aD2;
@@ -586,7 +586,7 @@ void CorrectWires(const TopoDS_Face& aFx)
continue;
}
//
aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
if (aD2>aD2max) {
aD2max=aD2;
}
@@ -606,7 +606,7 @@ void CorrectWires(const TopoDS_Face& aFx)
//=======================================================================
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
const GeomAdaptor_Surface& aGAS,
const Handle(Geom_Surface)& aS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2)
{
@@ -650,7 +650,7 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
}
//
aP2D = aPoint.Value();
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aS->D0(aP2D.X(), aP2D.Y(), aP);
aD=aPV.SquareDistance(aP);
if (aD > aDist) {
aDist = 1.01 * aD;

View File

@@ -74,8 +74,8 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
aCA.D0(aT, aPc);
Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast);
aC3D->D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
@@ -97,8 +97,8 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
GeomAdaptor_Curve aCA( aC.Curve() );
aCA.D0(aT, aPc);
Handle(Geom_Curve) aC3D=aC.Curve();
aC3D->D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;

View File

@@ -496,7 +496,6 @@ static inline Standard_Real ComputeToleranceVertex(const Standard_Real dist, con
{
return (dist * 0.5 + Tol1 + Tol2);
}
TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirst,
const TopoDS_Edge& edgeLast,
const TopTools_ListOfShape& listFacesFirst,
@@ -871,23 +870,15 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
}
Standard_Real tolReached = Precision::Infinite();
Standard_Boolean isSamePar = Standard_False;
try
if( isResEdge)
{
if( isResEdge)
SameParameter(edge);
SameParameter(edge);
if( BRep_Tool::SameParameter(edge))
{
isSamePar = Standard_True;
tolReached = BRep_Tool::Tolerance(edge);
}
}
catch(Standard_Failure)
{
isSamePar = Standard_False;
}
if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
@@ -914,10 +905,10 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
// Discretize edge curve
Standard_Integer i, j, nbp = 23;
Standard_Real deltaT = (last3d - first3d) / (nbp -1);
Standard_Real deltaT = (last3d - first3d) / (nbp + 1);
TColgp_Array1OfPnt c3dpnt(1,nbp);
for (i = 1; i <= nbp; i++)
c3dpnt(i) = c3dAdapt.Value(first3d + (i-1)*deltaT);
c3dpnt(i) = c3dAdapt.Value(first3d + i*deltaT);
Standard_Real dist = 0., maxTol = -1.0;
Standard_Boolean more = Standard_True;
@@ -933,9 +924,9 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
Standard_Real dist2 = 0.;
deltaT = (last - first) / (nbp - 1);
deltaT = (last - first) / (nbp + 1);
for (i = 1; i <= nbp; i++) {
gp_Pnt2d aP2d = c2d2->Value(first + (i -1)*deltaT);
gp_Pnt2d aP2d = c2d2->Value(first + i*deltaT);
gp_Pnt aP2(0.,0.,0.);
aS->D0(aP2d.X(),aP2d.Y(), aP2);
gp_Pnt aP1 = c3dpnt(i);

View File

@@ -108,7 +108,7 @@ inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
}
static
void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d);
@@ -1653,15 +1653,14 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
if(C2d.IsNull())
continue;
Geom2dAdaptor_Curve aCA(C2d);
aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
aPnt = aCA.Value(aParam);
aPnt = C2d->Value(aParam);
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
continue;
CurveDirForParameter(aCA, aParam, aPnt, aDer);
CurveDirForParameter(C2d, aParam, aPnt, aDer);
if (aVOrientation == anE.Orientation())
aDer.Reverse();
@@ -1754,21 +1753,21 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
//function : CurveDirForParameter
//purpose :
//=======================================================================
void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d)
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d)
{
Standard_Real aTol=gp::Resolution();
Standard_Integer i;
aC2d.D1(aPrm, Pnt, aVec2d);
aC2d->D1(aPrm, Pnt, aVec2d);
//
if (aVec2d.Magnitude() <= aTol) {
for (i = 2; i <= 100; i++){
aVec2d = aC2d.DN(aPrm, i);
aVec2d = aC2d->DN(aPrm, i);
if (aVec2d.Magnitude() > aTol) {
break;
break;
}
}
}

View File

@@ -50,7 +50,15 @@ is
-- face described by <F>.
is static;
Create(F : in out FaceExplorer from BRepClass;
P : Pnt from gp; Tol : Real)
returns FaceClassifier from BRepClass;
---Purpose: Creates an algorithm to classify the Point P with
-- Tolerance <T> on the face described by <F>.
Create(F : Face from TopoDS;
P : Pnt from gp; Tol : Real)
returns FaceClassifier from BRepClass;

View File

@@ -23,10 +23,6 @@
#include <TopoDS.hxx>
#include <BRep_Tool.hxx>
static const Standard_Real Probing_Start = 0.123;
static const Standard_Real Probing_End = 0.7;
static const Standard_Real Probing_Step = 0.2111;
//=======================================================================
//function : BRepClass_FaceExplorer
//purpose :
@@ -35,7 +31,7 @@ static const Standard_Real Probing_Step = 0.2111;
BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
myFace(F),
myCurEdgeInd(1),
myCurEdgePar(Probing_Start)
myCurEdgePar(0.123)
{
myFace.Orientation(TopAbs_FORWARD);
}
@@ -60,7 +56,7 @@ Standard_Boolean BRepClass_FaceExplorer::Segment(const gp_Pnt2d& P,
Standard_Real& Par)
{
myCurEdgeInd = 1;
myCurEdgePar = Probing_Start;
myCurEdgePar = 0.123;
return OtherSegment(P, L, Par);
}
@@ -79,7 +75,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
Standard_Real aFPar;
Standard_Real aLPar;
Handle(Geom2d_Curve) aC2d;
Standard_Real aTolParConf2 = Precision::PConfusion() * Precision::PConfusion();
Standard_Real aTolParConf = Precision::PConfusion();
gp_Pnt2d aPOnC;
Standard_Real aParamIn;
@@ -107,51 +103,32 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
} else if (Precision::IsPositiveInfinite(aLPar))
aLPar = aFPar + 1.;
for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
for (; myCurEdgePar < 0.7 ;myCurEdgePar += 0.2111) {
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
gp_Vec2d aTanVec;
aC2d->D1(aParamIn, aPOnC, aTanVec);
Par = aPOnC.SquareDistance(P);
aC2d->D0(aParamIn, aPOnC);
Par = aPOnC.Distance(P);
if (Par > aTolParConf2) {
if (Par > aTolParConf) {
gp_Vec2d aLinVec(P, aPOnC);
gp_Dir2d aLinDir(aLinVec);
Standard_Real aTanMod = aTanVec.SquareMagnitude();
if (aTanMod < aTolParConf2)
continue;
aTanVec /= Sqrt(aTanMod);
Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
const Standard_Real SmallAngle = 0.001;
if (Abs(aSinA) < SmallAngle)
{
// The line from the input point P to the current point on edge
// is tangent to the edge curve. This condition is bad for classification.
// Therefore try to go to another point in the hope that there will be
// no tangent. If there tangent is preserved then leave the last point in
// order to get this edge chanse to participate in classification.
if (myCurEdgePar + Probing_Step < Probing_End)
continue;
}
L = gp_Lin2d(P, aLinDir);
// Check if ends of a curve lie on a line.
aC2d->D0(aFPar, aPOnC);
if (L.SquareDistance(aPOnC) > aTolParConf2) {
if (L.Distance(aPOnC) > aTolParConf) {
aC2d->D0(aLPar, aPOnC);
if (L.SquareDistance(aPOnC) > aTolParConf2) {
myCurEdgePar += Probing_Step;
if (L.Distance(aPOnC) > aTolParConf) {
myCurEdgePar += 0.2111;
if (myCurEdgePar >= Probing_End) {
if (myCurEdgePar >= 0.7) {
myCurEdgeInd++;
myCurEdgePar = Probing_Start;
myCurEdgePar = 0.123;
}
Par = Sqrt(Par);
return Standard_True;
}
}
@@ -162,7 +139,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
// This curve is not valid for line construction. Go to another edge.
myCurEdgeInd++;
myCurEdgePar = Probing_Start;
myCurEdgePar = 0.123;
}
// nothing found, return an horizontal line

View File

@@ -1,48 +0,0 @@
// Created on: 2015-05-07
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepExtrema_ElementFilter_HeaderFile
#define _BRepExtrema_ElementFilter_HeaderFile
#include <Standard_TypeDef.hxx>
//! Filtering tool used to detect if two given mesh elements
//! should be tested for overlapping/intersection or not.
struct BRepExtrema_ElementFilter
{
//! Result of filtering function.
enum FilterResult
{
NoCheck,
Overlap,
DoCheck
};
//! Releases resources of element filter.
virtual ~BRepExtrema_ElementFilter()
{
//
}
//! Checks if two mesh elements should be tested for overlapping/intersection
//! (used for detection correct/incorrect cases of shared edges and vertices).
virtual FilterResult PreCheckElements (const Standard_Integer /*theIndex1*/,
const Standard_Integer /*theIndex2*/)
{
return DoCheck;
}
};
#endif // _BRepExtrema_ElementFilter_HeaderFile

View File

@@ -1,831 +0,0 @@
// Created on: 2015-04-26
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Precision.hxx>
#include <BRepExtrema_OverlapTool.hxx>
//=======================================================================
//function : BRepExtrema_OverlapTool
//purpose :
//=======================================================================
BRepExtrema_OverlapTool::BRepExtrema_OverlapTool()
: myFilter (NULL)
{
myIsDone = Standard_False;
}
//=======================================================================
//function : BRepExtrema_OverlapTool
//purpose :
//=======================================================================
BRepExtrema_OverlapTool::BRepExtrema_OverlapTool (const Handle(BRepExtrema_TriangleSet)& theSet1,
const Handle(BRepExtrema_TriangleSet)& theSet2)
: myFilter (NULL)
{
LoadTriangleSets (theSet1, theSet2);
}
//=======================================================================
//function : LoadTriangleSets
//purpose :
//=======================================================================
void BRepExtrema_OverlapTool::LoadTriangleSets (const Handle(BRepExtrema_TriangleSet)& theSet1,
const Handle(BRepExtrema_TriangleSet)& theSet2)
{
mySet1 = theSet1;
mySet2 = theSet2;
myIsDone = Standard_False;
}
#ifndef DBL_EPSILON
#define DBL_EPSILON std::numeric_limits<Standard_Real>::epsilon()
#endif
namespace
{
//! Tool class to describe stack item in traverse function.
struct BRepExtrema_StackItem
{
Standard_Integer Node1;
Standard_Integer Node2;
BRepExtrema_StackItem (const Standard_Integer theNode1 = 0,
const Standard_Integer theNode2 = 0)
: Node1 (theNode1),
Node2 (theNode2)
{
//
}
};
//! Bounding triangular prism for specified triangle.
class BRepExtrema_BoundingPrism
{
public:
//! Vertices of the prism.
BVH_Vec3d Vertices[6];
//! Edges of the prism.
BVH_Vec3d Edges[3];
//! Normal to prism caps.
BVH_Vec3d Normal;
//! Normals to prism edges.
BVH_Vec3d EdgeNormals[3];
//! Is prism initialized?
Standard_Boolean IsInited;
public:
//! Creates uninitialized bounding prism.
BRepExtrema_BoundingPrism() : IsInited (Standard_False)
{
//
}
//! Creates new bounding prism for the given triangle.
BRepExtrema_BoundingPrism (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Real theDeflect)
{
Init (theVertex0,
theVertex1,
theVertex2,
theDeflect);
}
//! Calculates bounding prism for the given triangle.
void Init (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Real theDeflect)
{
Edges[0] = theVertex1 - theVertex0;
Edges[1] = theVertex2 - theVertex0;
Edges[2] = theVertex2 - theVertex1;
Normal = BVH_Vec3d::Cross (Edges[0], Edges[1]);
EdgeNormals[0] = BVH_Vec3d::Cross (Edges[0], Normal);
EdgeNormals[1] = BVH_Vec3d::Cross (Edges[1], Normal);
EdgeNormals[2] = BVH_Vec3d::Cross (Edges[2], Normal);
EdgeNormals[0] *= 1.0 / Max (EdgeNormals[0].Modulus(), Precision::Confusion());
EdgeNormals[1] *= 1.0 / Max (EdgeNormals[1].Modulus(), Precision::Confusion());
EdgeNormals[2] *= 1.0 / Max (EdgeNormals[2].Modulus(), Precision::Confusion());
const BVH_Vec3d aDirect01 = EdgeNormals[0] - EdgeNormals[1];
const BVH_Vec3d aDirect02 = EdgeNormals[0] + EdgeNormals[2];
const BVH_Vec3d aDirect12 = EdgeNormals[2] - EdgeNormals[1];
Vertices[0] = Vertices[3] = theVertex0 + aDirect01 * (theDeflect / aDirect01.Dot (EdgeNormals[0]));
Vertices[1] = Vertices[4] = theVertex1 + aDirect02 * (theDeflect / aDirect02.Dot (EdgeNormals[2]));
Vertices[2] = Vertices[5] = theVertex2 + aDirect12 * (theDeflect / aDirect12.Dot (EdgeNormals[2]));
const BVH_Vec3d aNormOffset = Normal * (theDeflect / Max (Normal.Modulus(), Precision::Confusion()));
for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx)
{
Vertices[aVertIdx + 0] += aNormOffset;
Vertices[aVertIdx + 3] -= aNormOffset;
}
IsInited = Standard_True;
}
//! Checks if two prisms are separated along the given axis.
Standard_Boolean Separated (const BRepExtrema_BoundingPrism& thePrism, const BVH_Vec3d& theAxis) const
{
Standard_Real aMin1 = DBL_MAX;
Standard_Real aMax1 = -DBL_MAX;
Standard_Real aMin2 = DBL_MAX;
Standard_Real aMax2 = -DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
{
const Standard_Real aProj1 = Vertices[aVertIdx].Dot (theAxis);
aMin1 = Min (aMin1, aProj1);
aMax1 = Max (aMax1, aProj1);
const Standard_Real aProj2 = thePrism.Vertices[aVertIdx].Dot (theAxis);
aMin2 = Min (aMin2, aProj2);
aMax2 = Max (aMax2, aProj2);
if (aMin1 <= aMax2 && aMax1 >= aMin2)
{
return Standard_False;
}
}
return aMin1 > aMax2 || aMax1 < aMin2;
}
};
// =======================================================================
// function : sign
// purpose :
// =======================================================================
Standard_Real sign (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Integer theX,
const Standard_Integer theY)
{
return (theVertex0[theX] - theVertex2[theX]) * (theVertex1[theY] - theVertex2[theY]) -
(theVertex1[theX] - theVertex2[theX]) * (theVertex0[theY] - theVertex2[theY]);
}
// =======================================================================
// function : pointInTriangle
// purpose :
// =======================================================================
Standard_Boolean pointInTriangle (const BVH_Vec3d& theTestPnt,
const BVH_Vec3d& theTrgVtx0,
const BVH_Vec3d& theTrgVtx1,
const BVH_Vec3d& theTrgVtx2,
const Standard_Integer theX,
const Standard_Integer theY)
{
const Standard_Boolean aSign0 = sign (theTestPnt, theTrgVtx0, theTrgVtx1, theX, theY) <= 0.0;
const Standard_Boolean aSign1 = sign (theTestPnt, theTrgVtx1, theTrgVtx2, theX, theY) <= 0.0;
const Standard_Boolean aSign2 = sign (theTestPnt, theTrgVtx2, theTrgVtx0, theX, theY) <= 0.0;
return (aSign0 == aSign1) && (aSign1 == aSign2);
}
// =======================================================================
// function : segmentsIntersected
// purpose : Checks if two line segments are intersected
// =======================================================================
Standard_Boolean segmentsIntersected (const BVH_Vec2d& theOriginSeg0,
const BVH_Vec2d& theOriginSeg1,
const BVH_Vec2d& theDirectSeg0,
const BVH_Vec2d& theDirectSeg1)
{
const Standard_Real aDet = -theDirectSeg1.x() * theDirectSeg0.y() +
theDirectSeg0.x() * theDirectSeg1.y();
if (fabs (aDet) < DBL_EPSILON) // segments are parallel
{
const BVH_Vec2d aDirect = theDirectSeg0 * (1.0 / theDirectSeg0.Modulus());
const Standard_Real aEdge0Time0 = theOriginSeg0.Dot (aDirect);
const Standard_Real aEdge1Time0 = theOriginSeg1.Dot (aDirect);
const Standard_Real aEdge0Time1 = aEdge0Time0 + theDirectSeg0.Dot (aDirect);
const Standard_Real aEdge1Time1 = aEdge1Time0 + theDirectSeg1.Dot (aDirect);
const Standard_Real aEdge0Min = Min (aEdge0Time0, aEdge0Time1);
const Standard_Real aEdge1Min = Min (aEdge1Time0, aEdge1Time1);
const Standard_Real aEdge0Max = Max (aEdge0Time0, aEdge0Time1);
const Standard_Real aEdge1Max = Max (aEdge1Time0, aEdge1Time1);
if (Max (aEdge0Min, aEdge1Min) > Min (aEdge0Max, aEdge1Max))
{
return Standard_False;
}
const BVH_Vec2d aNormal (-aDirect.y(), aDirect.x());
return fabs (theOriginSeg0.Dot (aNormal) - theOriginSeg1.Dot (aNormal)) < DBL_EPSILON;
}
const BVH_Vec2d aDelta = theOriginSeg0 - theOriginSeg1;
const Standard_Real aU = (-theDirectSeg0.y() * aDelta.x() + theDirectSeg0.x() * aDelta.y()) / aDet;
const Standard_Real aV = ( theDirectSeg1.x() * aDelta.y() - theDirectSeg1.y() * aDelta.x()) / aDet;
return aU >= 0.0 && aU <= 1.0 && aV >= 0.0 && aV <= 1.0;
}
// =======================================================================
// function : trianglesIntersected
// purpose : Checks if two triangles are intersected
// ("A Fast Triangle-Triangle Intersection Test" by T. Moller)
// =======================================================================
Standard_Boolean trianglesIntersected (const BVH_Vec3d& theTrng0Vert0,
const BVH_Vec3d& theTrng0Vert1,
const BVH_Vec3d& theTrng0Vert2,
const BVH_Vec3d& theTrng1Vert0,
const BVH_Vec3d& theTrng1Vert1,
const BVH_Vec3d& theTrng1Vert2)
{
const BVH_Vec3d aTrng1Normal = BVH_Vec3d::Cross (theTrng1Vert1 - theTrng1Vert0,
theTrng1Vert2 - theTrng1Vert0).Normalized();
const Standard_Real aTrng1PlaneDist = aTrng1Normal.Dot (-theTrng1Vert0);
Standard_Real aDistTrng0Vert0 = aTrng1Normal.Dot (theTrng0Vert0) + aTrng1PlaneDist;
Standard_Real aDistTrng0Vert1 = aTrng1Normal.Dot (theTrng0Vert1) + aTrng1PlaneDist;
Standard_Real aDistTrng0Vert2 = aTrng1Normal.Dot (theTrng0Vert2) + aTrng1PlaneDist;
if ((aDistTrng0Vert0 < 0.0 && aDistTrng0Vert1 < 0.0 && aDistTrng0Vert2 < 0.0)
|| (aDistTrng0Vert0 > 0.0 && aDistTrng0Vert1 > 0.0 && aDistTrng0Vert2 > 0.0))
{
return Standard_False; // 1st triangle lies on one side of the 2nd triangle
}
if (fabs (aDistTrng0Vert0) > Precision::Confusion()
|| fabs (aDistTrng0Vert1) > Precision::Confusion()
|| fabs (aDistTrng0Vert2) > Precision::Confusion()) // general 3D case
{
const BVH_Vec3d aTrng0Normal = BVH_Vec3d::Cross (theTrng0Vert1 - theTrng0Vert0,
theTrng0Vert2 - theTrng0Vert0).Normalized();
const Standard_Real aTrng0PlaneDist = aTrng0Normal.Dot (-theTrng0Vert0);
Standard_Real aDistTrng1Vert0 = aTrng0Normal.Dot (theTrng1Vert0) + aTrng0PlaneDist;
Standard_Real aDistTrng1Vert1 = aTrng0Normal.Dot (theTrng1Vert1) + aTrng0PlaneDist;
Standard_Real aDistTrng1Vert2 = aTrng0Normal.Dot (theTrng1Vert2) + aTrng0PlaneDist;
if ((aDistTrng1Vert0 < 0.0 && aDistTrng1Vert1 < 0.0 && aDistTrng1Vert2 < 0.0)
|| (aDistTrng1Vert0 > 0.0 && aDistTrng1Vert1 > 0.0 && aDistTrng1Vert2 > 0.0))
{
return Standard_False; // 2nd triangle lies on one side of the 1st triangle
}
const BVH_Vec3d aCrossLine = BVH_Vec3d::Cross (aTrng0Normal,
aTrng1Normal);
Standard_Real aProjTrng0Vert0 = theTrng0Vert0.Dot (aCrossLine);
Standard_Real aProjTrng0Vert1 = theTrng0Vert1.Dot (aCrossLine);
Standard_Real aProjTrng0Vert2 = theTrng0Vert2.Dot (aCrossLine);
if (aDistTrng0Vert0 * aDistTrng0Vert1 > 0.0)
{
std::swap (aDistTrng0Vert1, aDistTrng0Vert2);
std::swap (aProjTrng0Vert1, aProjTrng0Vert2);
}
else if (aDistTrng0Vert1 * aDistTrng0Vert2 > 0.0)
{
std::swap (aDistTrng0Vert1, aDistTrng0Vert0);
std::swap (aProjTrng0Vert1, aProjTrng0Vert0);
}
Standard_Real aTime1 = fabs (aDistTrng0Vert0) <= DBL_EPSILON ? aProjTrng0Vert0 :
aProjTrng0Vert0 + (aProjTrng0Vert1 - aProjTrng0Vert0) * aDistTrng0Vert0 / (aDistTrng0Vert0 - aDistTrng0Vert1);
Standard_Real aTime2 = fabs (aDistTrng0Vert2) <= DBL_EPSILON ? aProjTrng0Vert2 :
aProjTrng0Vert2 + (aProjTrng0Vert1 - aProjTrng0Vert2) * aDistTrng0Vert2 / (aDistTrng0Vert2 - aDistTrng0Vert1);
const Standard_Real aTimeMin1 = Min (aTime1, aTime2);
const Standard_Real aTimeMax1 = Max (aTime1, aTime2);
Standard_Real aProjTrng1Vert0 = theTrng1Vert0.Dot (aCrossLine);
Standard_Real aProjTrng1Vert1 = theTrng1Vert1.Dot (aCrossLine);
Standard_Real aProjTrng1Vert2 = theTrng1Vert2.Dot (aCrossLine);
if (aDistTrng1Vert0 * aDistTrng1Vert1 > 0.0)
{
std::swap (aDistTrng1Vert1, aDistTrng1Vert2);
std::swap (aProjTrng1Vert1, aProjTrng1Vert2);
}
else if (aDistTrng1Vert1 * aDistTrng1Vert2 > 0.0)
{
std::swap (aDistTrng1Vert1, aDistTrng1Vert0);
std::swap (aProjTrng1Vert1, aProjTrng1Vert0);
}
aTime1 = fabs (aDistTrng1Vert0) <= DBL_EPSILON ? aProjTrng1Vert0 :
aProjTrng1Vert0 + (aProjTrng1Vert1 - aProjTrng1Vert0) * aDistTrng1Vert0 / (aDistTrng1Vert0 - aDistTrng1Vert1);
aTime2 = fabs (aDistTrng1Vert2) <= DBL_EPSILON ? aProjTrng1Vert2 :
aProjTrng1Vert2 + (aProjTrng1Vert1 - aProjTrng1Vert2) * aDistTrng1Vert2 / (aDistTrng1Vert2 - aDistTrng1Vert1);
const Standard_Real aTimeMin2 = Min (aTime1, aTime2);
const Standard_Real aTimeMax2 = Max (aTime1, aTime2);
aTime1 = Max (aTimeMin1, aTimeMin2);
aTime2 = Min (aTimeMax1, aTimeMax2);
return aTime1 <= aTime2; // intervals intersected --> triangles overlapped
}
else // triangles are co-planar
{
Standard_Integer anX;
Standard_Integer anY;
if (fabs (aTrng1Normal[0]) > fabs (aTrng1Normal[1]))
{
anX = fabs (aTrng1Normal[0]) > fabs (aTrng1Normal[2]) ? 1 : 0;
anY = fabs (aTrng1Normal[0]) > fabs (aTrng1Normal[2]) ? 2 : 1;
}
else
{
anX = fabs (aTrng1Normal[1]) > fabs (aTrng1Normal[2]) ? 0 : 0;
anY = fabs (aTrng1Normal[1]) > fabs (aTrng1Normal[2]) ? 2 : 1;
}
const BVH_Vec2d aOriginSeg0 [] = {BVH_Vec2d (theTrng0Vert0[anX], theTrng0Vert0[anY]),
BVH_Vec2d (theTrng0Vert1[anX], theTrng0Vert1[anY]),
BVH_Vec2d (theTrng0Vert2[anX], theTrng0Vert2[anY]) };
const BVH_Vec2d aDirectSeg0 [] = {aOriginSeg0[1] - aOriginSeg0[0],
aOriginSeg0[2] - aOriginSeg0[1],
aOriginSeg0[0] - aOriginSeg0[2] };
const BVH_Vec2d aOriginSeg1 [] = {BVH_Vec2d (theTrng1Vert0[anX], theTrng1Vert0[anY]),
BVH_Vec2d (theTrng1Vert1[anX], theTrng1Vert1[anY]),
BVH_Vec2d (theTrng1Vert2[anX], theTrng1Vert2[anY]) };
const BVH_Vec2d aDirectSeg1 [] = {aOriginSeg1[1] - aOriginSeg1[0],
aOriginSeg1[2] - aOriginSeg1[1],
aOriginSeg1[0] - aOriginSeg1[2] };
for (Standard_Integer aTrg0Edge = 0; aTrg0Edge < 3; ++aTrg0Edge)
{
for (Standard_Integer aTrg1Edge = 0; aTrg1Edge < 3; ++aTrg1Edge)
{
if (segmentsIntersected (aOriginSeg0[aTrg0Edge],
aOriginSeg1[aTrg1Edge],
aDirectSeg0[aTrg0Edge],
aDirectSeg1[aTrg1Edge]))
{
return Standard_True; // edges intersected --> triangles overlapped
}
}
}
if (pointInTriangle (theTrng1Vert0,
theTrng0Vert0,
theTrng0Vert1,
theTrng0Vert2,
anX,
anY))
{
return Standard_True; // 1st triangle inside 2nd --> triangles overlapped
}
if (pointInTriangle (theTrng0Vert0,
theTrng1Vert0,
theTrng1Vert1,
theTrng1Vert2,
anX,
anY))
{
return Standard_True; // 2nd triangle inside 1st --> triangles overlapped
}
}
return Standard_False;
}
// =======================================================================
// function : prismsIntersected
// purpose : Checks if two triangular prisms are intersected
// (test uses SAT - Separating Axis Theorem)
// =======================================================================
Standard_Boolean prismsIntersected (const BRepExtrema_BoundingPrism& thePrism1,
const BRepExtrema_BoundingPrism& thePrism2)
{
if (thePrism1.Separated (thePrism2, thePrism1.Normal))
{
return Standard_False;
}
if (thePrism1.Separated (thePrism2, thePrism2.Normal))
{
return Standard_False;
}
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (thePrism1.Separated (thePrism2, thePrism1.EdgeNormals[anIdx]))
{
return Standard_False;
}
}
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (thePrism1.Separated (thePrism2, thePrism2.EdgeNormals[anIdx]))
{
return Standard_False;
}
}
for (Standard_Integer anIdx1 = 0; anIdx1 < 4; ++anIdx1)
{
const BVH_Vec3d& aEdge1 = (anIdx1 == 3) ? thePrism1.Normal : thePrism1.Edges[anIdx1];
for (Standard_Integer anIdx2 = 0; anIdx2 < 4; ++anIdx2)
{
const BVH_Vec3d& aEdge2 = (anIdx2 == 3) ? thePrism2.Normal : thePrism2.Edges[anIdx2];
if (thePrism1.Separated (thePrism2, BVH_Vec3d::Cross (aEdge1, aEdge2)))
{
return Standard_False;
}
}
}
return Standard_True;
}
// =======================================================================
// function : overlapBoxes
// purpose : Checks if two boxes (AABBs) are overlapped
// =======================================================================
inline Standard_Boolean overlapBoxes (const BVH_Vec3d& theBoxMin1,
const BVH_Vec3d& theBoxMax1,
const BVH_Vec3d& theBoxMin2,
const BVH_Vec3d& theBoxMax2,
const Standard_Real theTolerance)
{
// Check for overlap
return !(theBoxMin1.x() > theBoxMax2.x() + theTolerance ||
theBoxMax1.x() < theBoxMin2.x() - theTolerance ||
theBoxMin1.y() > theBoxMax2.y() + theTolerance ||
theBoxMax1.y() < theBoxMin2.y() - theTolerance ||
theBoxMin1.z() > theBoxMax2.z() + theTolerance ||
theBoxMax1.z() < theBoxMin2.z() - theTolerance);
}
//=======================================================================
//function : getSetOfFaces
//purpose :
//=======================================================================
TColStd_PackedMapOfInteger& getSetOfFaces (
BRepExtrema_MapOfIntegerPackedMapOfInteger& theFaces, const Standard_Integer theFaceIdx)
{
if (!theFaces.IsBound (theFaceIdx))
{
theFaces.Bind (theFaceIdx, TColStd_PackedMapOfInteger());
}
return theFaces.ChangeFind (theFaceIdx);
}
}
//=======================================================================
//function : intersectTriangleRangesExact
//purpose :
//=======================================================================
void BRepExtrema_OverlapTool::intersectTriangleRangesExact (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2)
{
for (Standard_Integer aTrgIdx1 = theLeaf1.y(); aTrgIdx1 <= theLeaf1.z(); ++aTrgIdx1)
{
const Standard_Integer aFaceIdx1 = mySet1->GetFaceID (aTrgIdx1);
BVH_Vec3d aTrg1Vert1;
BVH_Vec3d aTrg1Vert2;
BVH_Vec3d aTrg1Vert3;
mySet1->GetVertices (aTrgIdx1,
aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3);
const Standard_Boolean aIsInSet = myOverlapSubShapes1.IsBound (aFaceIdx1);
for (Standard_Integer aTrgIdx2 = theLeaf2.y(); aTrgIdx2 <= theLeaf2.z(); ++aTrgIdx2)
{
const Standard_Integer aFaceIdx2 = mySet2->GetFaceID (aTrgIdx2);
if (aIsInSet && myOverlapSubShapes1.Find (aFaceIdx1).Contains (aFaceIdx2))
{
continue;
}
BRepExtrema_ElementFilter::FilterResult aResult = myFilter == NULL ?
BRepExtrema_ElementFilter::DoCheck : myFilter->PreCheckElements (aTrgIdx1, aTrgIdx2);
if (aResult == BRepExtrema_ElementFilter::Overlap)
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
if (mySet1 == mySet2)
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles1.Add (aTrgIdx2);
}
else
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles2.Add (aTrgIdx2);
}
#endif
}
else if (aResult == BRepExtrema_ElementFilter::DoCheck)
{
BVH_Vec3d aTrg2Vert1;
BVH_Vec3d aTrg2Vert2;
BVH_Vec3d aTrg2Vert3;
mySet2->GetVertices (aTrgIdx2, aTrg2Vert1, aTrg2Vert2, aTrg2Vert3);
if (trianglesIntersected (aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3,
aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3))
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
if (mySet1 == mySet2)
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles1.Add (aTrgIdx2);
}
else
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles2.Add (aTrgIdx2);
}
#endif
}
}
}
}
}
//=======================================================================
//function : intersectTriangleRangesToler
//purpose :
//=======================================================================
void BRepExtrema_OverlapTool::intersectTriangleRangesToler (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2,
const Standard_Real theToler)
{
for (Standard_Integer aTrgIdx1 = theLeaf1.y(); aTrgIdx1 <= theLeaf1.z(); ++aTrgIdx1)
{
const Standard_Integer aFaceIdx1 = mySet1->GetFaceID (aTrgIdx1);
BVH_Vec3d aTrg1Vert1;
BVH_Vec3d aTrg1Vert2;
BVH_Vec3d aTrg1Vert3;
mySet1->GetVertices (aTrgIdx1,
aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3);
BRepExtrema_BoundingPrism aPrism1; // not initialized
const Standard_Boolean aIsInSet = myOverlapSubShapes1.IsBound (aFaceIdx1);
for (Standard_Integer aTrgIdx2 = theLeaf2.y(); aTrgIdx2 <= theLeaf2.z(); ++aTrgIdx2)
{
const Standard_Integer aFaceIdx2 = mySet2->GetFaceID (aTrgIdx2);
if (aIsInSet && myOverlapSubShapes1.Find (aFaceIdx1).Contains (aFaceIdx2))
{
continue;
}
BRepExtrema_ElementFilter::FilterResult aResult = myFilter == NULL ?
BRepExtrema_ElementFilter::DoCheck : myFilter->PreCheckElements (aTrgIdx1, aTrgIdx2);
if (aResult == BRepExtrema_ElementFilter::Overlap)
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
if (mySet1 == mySet2)
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles1.Add (aTrgIdx2);
}
else
{
myOverlapTriangles1.Add (aTrgIdx1);
myOverlapTriangles2.Add (aTrgIdx2);
}
#endif
}
else if (aResult == BRepExtrema_ElementFilter::DoCheck)
{
if (!aPrism1.IsInited)
{
aPrism1.Init (aTrg1Vert1, aTrg1Vert2, aTrg1Vert3, theToler);
}
BVH_Vec3d aTrg2Vert1;
BVH_Vec3d aTrg2Vert2;
BVH_Vec3d aTrg2Vert3;
mySet2->GetVertices (aTrgIdx2,
aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3);
BRepExtrema_BoundingPrism aPrism2 (aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3,
theToler);
if (prismsIntersected (aPrism1, aPrism2))
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
}
}
}
}
}
//=======================================================================
//function : Perform
//purpose : Performs search for overlapped faces
//=======================================================================
void BRepExtrema_OverlapTool::Perform (const Standard_Real theTolerance)
{
if (mySet1.IsNull() || mySet2.IsNull())
{
return;
}
BRepExtrema_StackItem aStack[96];
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH1 = mySet1->BVH();
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH2 = mySet2->BVH();
if (aBVH1.IsNull() || aBVH2.IsNull())
{
return;
}
BRepExtrema_StackItem aNodes; // current pair of nodes
Standard_Integer aHead = -1; // stack head position
for (;;)
{
BVH_Vec4i aNodeData1 = aBVH1->NodeInfoBuffer()[aNodes.Node1];
BVH_Vec4i aNodeData2 = aBVH2->NodeInfoBuffer()[aNodes.Node2];
if (aNodeData1.x() != 0 && aNodeData2.x() != 0) // leaves
{
if (theTolerance == 0.0)
{
intersectTriangleRangesExact (aNodeData1, aNodeData2);
}
else
{
intersectTriangleRangesToler (aNodeData1, aNodeData2, theTolerance);
}
if (aHead < 0)
break;
aNodes = aStack[aHead--];
}
else
{
BRepExtrema_StackItem aPairsToProcess[4];
Standard_Integer aNbPairs = 0;
if (aNodeData1.x() == 0) // inner node
{
const BVH_Vec3d& aMinPntLft1 = aBVH1->MinPoint (aNodeData1.y());
const BVH_Vec3d& aMaxPntLft1 = aBVH1->MaxPoint (aNodeData1.y());
const BVH_Vec3d& aMinPntRgh1 = aBVH1->MinPoint (aNodeData1.z());
const BVH_Vec3d& aMaxPntRgh1 = aBVH1->MaxPoint (aNodeData1.z());
if (aNodeData2.x() == 0) // inner node
{
const BVH_Vec3d& aMinPntLft2 = aBVH2->MinPoint (aNodeData2.y());
const BVH_Vec3d& aMaxPntLft2 = aBVH2->MaxPoint (aNodeData2.y());
const BVH_Vec3d& aMinPntRgh2 = aBVH2->MinPoint (aNodeData2.z());
const BVH_Vec3d& aMaxPntRgh2 = aBVH2->MaxPoint (aNodeData2.z());
if (overlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntLft2, aMaxPntLft2, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodeData2.y());
}
if (overlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntRgh2, aMaxPntRgh2, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodeData2.z());
}
if (overlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntLft2, aMaxPntLft2, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodeData2.y());
}
if (overlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntRgh2, aMaxPntRgh2, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodeData2.z());
}
}
else
{
const BVH_Vec3d& aMinPntLeaf = aBVH2->MinPoint (aNodes.Node2);
const BVH_Vec3d& aMaxPntLeaf = aBVH2->MaxPoint (aNodes.Node2);
if (overlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntLeaf, aMaxPntLeaf, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodes.Node2);
}
if (overlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntLeaf, aMaxPntLeaf, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodes.Node2);
}
}
}
else
{
const BVH_Vec3d& aMinPntLeaf = aBVH1->MinPoint (aNodes.Node1);
const BVH_Vec3d& aMaxPntLeaf = aBVH1->MaxPoint (aNodes.Node1);
const BVH_Vec3d& aMinPntLft2 = aBVH2->MinPoint (aNodeData2.y());
const BVH_Vec3d& aMaxPntLft2 = aBVH2->MaxPoint (aNodeData2.y());
const BVH_Vec3d& aMinPntRgh2 = aBVH2->MinPoint (aNodeData2.z());
const BVH_Vec3d& aMaxPntRgh2 = aBVH2->MaxPoint (aNodeData2.z());
if (overlapBoxes (aMinPntLft2, aMaxPntLft2, aMinPntLeaf, aMaxPntLeaf, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodes.Node1, aNodeData2.y());
}
if (overlapBoxes (aMinPntRgh2, aMaxPntRgh2, aMinPntLeaf, aMaxPntLeaf, theTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodes.Node1, aNodeData2.z());
}
}
if (aNbPairs > 0)
{
aNodes = aPairsToProcess[0];
for (Standard_Integer anIdx = 1; anIdx < aNbPairs; ++anIdx)
{
aStack[++aHead] = aPairsToProcess[anIdx];
}
}
else
{
if (aHead < 0)
break;
aNodes = aStack[aHead--];
}
}
}
myIsDone = Standard_True;
}

View File

@@ -1,118 +0,0 @@
// Created on: 2015-04-26
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepExtrema_OverlapTool_HeaderFile
#define _BRepExtrema_OverlapTool_HeaderFile
#include <BVH_Geometry.hxx>
#include <BRepExtrema_TriangleSet.hxx>
#include <BRepExtrema_ElementFilter.hxx>
#include <BRepExtrema_MapOfIntegerPackedMapOfInteger.hxx>
//! Enables storing of individual overlapped triangles (useful for debug).
// #define OVERLAP_TOOL_OUTPUT_TRIANGLES
//! Tool class for for detection of overlapping of two BVH primitive sets.
//! This tool is not intended to be used independently, and is integrated
//! in other classes, implementing algorithms based on shape tessellation
//! (BRepExtrema_ShapeProximity and BRepExtrema_SelfIntersection).
//!
//! Note that input element sets may correspond to different shapes or to
//! the same shape. In first case, tessellations of two given shapes will
//! be tested for intersection (or overlapping, if tolerance is not zero).
//! In second case, tessellation of single shape will be tested for self-
//! intersections. Please note that algorithm results are approximate and
//! depend greatly on the quality of input tessellation(s).
class BRepExtrema_OverlapTool
{
public:
//! Creates new unitialized overlap tool.
BRepExtrema_OverlapTool();
//! Creates new overlap tool for the given element sets.
BRepExtrema_OverlapTool (const Handle(BRepExtrema_TriangleSet)& theSet1,
const Handle(BRepExtrema_TriangleSet)& theSet2);
public:
//! Loads the given element sets into the overlap tool.
void LoadTriangleSets (const Handle(BRepExtrema_TriangleSet)& theSet1,
const Handle(BRepExtrema_TriangleSet)& theSet2);
//! Performs searching of overlapped mesh elements.
void Perform (const Standard_Real theTolerance = 0.0);
//! Is overlap test completed?
Standard_Boolean IsDone() const { return myIsDone; }
//! Marks test results as outdated.
void MarkDirty() { myIsDone = Standard_False; }
//! Returns set of overlapped sub-shapes of 1st shape (currently only faces are detected).
const BRepExtrema_MapOfIntegerPackedMapOfInteger& OverlapSubShapes1() const { return myOverlapSubShapes1; }
//! Returns set of overlapped sub-shapes of 2nd shape (currently only faces are detected).
const BRepExtrema_MapOfIntegerPackedMapOfInteger& OverlapSubShapes2() const { return myOverlapSubShapes2; }
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
//! Returns set of overlapped triangles from the 1st shape (for debug).
const TColStd_PackedMapOfInteger& OverlapTriangles1() const { return myOverlapTriangles1; }
//! Returns set of overlapped triangles from the 2nd shape (for debug).
const TColStd_PackedMapOfInteger& OverlapTriangles2() const { return myOverlapTriangles2; }
#endif
//! Sets filtering tool for preliminary checking pairs of mesh elements.
void SetElementFilter (BRepExtrema_ElementFilter* theFilter) { myFilter = theFilter; }
protected:
//! Performs narrow-phase of overlap test (exact intersection).
void intersectTriangleRangesExact (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2);
//! Performs narrow-phase of overlap test (intersection with non-zero tolerance).
void intersectTriangleRangesToler (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2,
const Standard_Real theToler);
private:
//! Set of all mesh elements (triangles) of the 1st shape.
Handle(BRepExtrema_TriangleSet) mySet1;
//! Set of all mesh elements (triangles) of the 2nd shape.
Handle(BRepExtrema_TriangleSet) mySet2;
//! Filter for preliminary checking pairs of mesh elements.
BRepExtrema_ElementFilter* myFilter;
//! Resulted set of overlapped sub-shapes of 1st shape (only faces).
BRepExtrema_MapOfIntegerPackedMapOfInteger myOverlapSubShapes1;
//! Resulted set of overlapped sub-shapes of 2nd shape (only faces).
BRepExtrema_MapOfIntegerPackedMapOfInteger myOverlapSubShapes2;
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
//! Set of overlapped elements from the 1st shape (only triangles).
TColStd_PackedMapOfInteger myOverlapTriangles1;
//! Set of overlapped elements from the 2nd shape (only triangles).
TColStd_PackedMapOfInteger myOverlapTriangles2;
#endif
//! Is overlap test test completed?
Standard_Boolean myIsDone;
};
#endif // _BRepExtrema_OverlapTool_HeaderFile

View File

@@ -1,312 +0,0 @@
// Created on: 2015-04-26
// Created by: Denis BOGOLEPOV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepExtrema_SelfIntersection.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
//=======================================================================
//function : BRepExtrema_SelfIntersection
//purpose :
//=======================================================================
BRepExtrema_SelfIntersection::BRepExtrema_SelfIntersection (const Standard_Real theTolerance)
: myTolerance (theTolerance)
{
myIsInit = Standard_False;
}
//=======================================================================
//function : BRepExtrema_SelfIntersection
//purpose :
//=======================================================================
BRepExtrema_SelfIntersection::BRepExtrema_SelfIntersection (const TopoDS_Shape& theShape, const Standard_Real theTolerance)
: myTolerance (theTolerance)
{
LoadShape (theShape);
}
//=======================================================================
//function : LoadShape
//purpose :
//=======================================================================
Standard_Boolean BRepExtrema_SelfIntersection::LoadShape (const TopoDS_Shape& theShape)
{
myFaceList.Clear();
for (TopExp_Explorer anIter (theShape, TopAbs_FACE); anIter.More(); anIter.Next())
{
myFaceList.Append (static_cast<const TopoDS_Face&> (anIter.Current()));
}
if (myElementSet.IsNull())
{
myElementSet = new BRepExtrema_TriangleSet;
}
myIsInit = myElementSet->Init (myFaceList);
if (myIsInit)
{
myOverlapTool.LoadTriangleSets (myElementSet,
myElementSet);
}
return myIsInit;
}
#define ZERO_VEC BVH_Vec3d (0.0, 0.0, 0.0)
namespace
{
// =======================================================================
// function : ccw
// purpose : Check if triple is in counterclockwise order
// =======================================================================
Standard_Boolean ccw (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Integer theX,
const Standard_Integer theY)
{
const Standard_Real aSum =
(theVertex1[theX] - theVertex0[theX]) * (theVertex1[theY] + theVertex0[theY]) +
(theVertex2[theX] - theVertex1[theX]) * (theVertex2[theY] + theVertex1[theY]) +
(theVertex0[theX] - theVertex2[theX]) * (theVertex0[theY] + theVertex2[theY]);
return aSum < 0.0;
}
// =======================================================================
// function : rayInsideAngle
// purpose : Check the given ray is inside the angle
// =======================================================================
Standard_Boolean rayInsideAngle (const BVH_Vec3d& theDirec,
const BVH_Vec3d& theEdge0,
const BVH_Vec3d& theEdge1,
const Standard_Integer theX,
const Standard_Integer theY)
{
const Standard_Boolean aCCW = ccw (ZERO_VEC, theEdge0, theEdge1, theX, theY);
return ccw (ZERO_VEC, theEdge0, theDirec, theX, theY) == aCCW
&& ccw (ZERO_VEC, theDirec, theEdge1, theX, theY) == aCCW;
}
// =======================================================================
// function : getProjectionAxes
// purpose :
// =======================================================================
void getProjectionAxes (const BVH_Vec3d& theNorm,
Standard_Integer& theAxisX,
Standard_Integer& theAxisY)
{
if (fabs (theNorm[0]) > fabs (theNorm[1]))
{
theAxisX = fabs (theNorm[0]) > fabs (theNorm[2]) ? 1 : 0;
theAxisY = fabs (theNorm[0]) > fabs (theNorm[2]) ? 2 : 1;
}
else
{
theAxisX = fabs (theNorm[1]) > fabs (theNorm[2]) ? 0 : 0;
theAxisY = fabs (theNorm[1]) > fabs (theNorm[2]) ? 2 : 1;
}
}
}
//=======================================================================
//function : isRegularSharedVertex
//purpose :
//=======================================================================
BRepExtrema_ElementFilter::FilterResult BRepExtrema_SelfIntersection::isRegularSharedVertex (const BVH_Vec3d& theSharedVert,
const BVH_Vec3d& theTrng0Vtxs1,
const BVH_Vec3d& theTrng0Vtxs2,
const BVH_Vec3d& theTrng1Vtxs1,
const BVH_Vec3d& theTrng1Vtxs2)
{
const BVH_Vec3d aTrng0Edges[] = { (theTrng0Vtxs1 - theSharedVert).Normalized(),
(theTrng0Vtxs2 - theSharedVert).Normalized() };
const BVH_Vec3d aTrng1Edges[] = { (theTrng1Vtxs1 - theSharedVert).Normalized(),
(theTrng1Vtxs2 - theSharedVert).Normalized() };
const BVH_Vec3d aTrng0Normal = BVH_Vec3d::Cross (aTrng0Edges[0], aTrng0Edges[1]);
const BVH_Vec3d aTrng1Normal = BVH_Vec3d::Cross (aTrng1Edges[0], aTrng1Edges[1]);
BVH_Vec3d aCrossLine = BVH_Vec3d::Cross (aTrng0Normal,
aTrng1Normal);
Standard_Integer anX;
Standard_Integer anY;
if (aCrossLine.SquareModulus() < Precision::SquareConfusion()) // coplanar case
{
getProjectionAxes (aTrng0Normal, anX, anY);
if (rayInsideAngle (aTrng1Edges[0], aTrng0Edges[0], aTrng0Edges[1], anX, anY)
|| rayInsideAngle (aTrng1Edges[1], aTrng0Edges[0], aTrng0Edges[1], anX, anY)
|| rayInsideAngle (aTrng0Edges[0], aTrng1Edges[0], aTrng1Edges[1], anX, anY)
|| rayInsideAngle (aTrng0Edges[1], aTrng1Edges[0], aTrng1Edges[1], anX, anY))
{
return BRepExtrema_ElementFilter::Overlap;
}
return BRepExtrema_ElementFilter::NoCheck;
}
else // shared line should lie outside at least one triangle
{
getProjectionAxes (aTrng0Normal, anX, anY);
const Standard_Boolean aPosOutTrgn0 = !rayInsideAngle ( aCrossLine, aTrng0Edges[0], aTrng0Edges[1], anX, anY);
const Standard_Boolean aNegOutTrgn0 = !rayInsideAngle (-aCrossLine, aTrng0Edges[0], aTrng0Edges[1], anX, anY);
Standard_ASSERT_RAISE (aPosOutTrgn0 || aNegOutTrgn0,
"Failed to detect if shared vertex is regular or not");
if (aPosOutTrgn0 && aNegOutTrgn0)
{
return BRepExtrema_ElementFilter::NoCheck;
}
getProjectionAxes (aTrng1Normal, anX, anY);
const Standard_Boolean aPosOutTrgn1 = !rayInsideAngle ( aCrossLine, aTrng1Edges[0], aTrng1Edges[1], anX, anY);
const Standard_Boolean aNegOutTrgn1 = !rayInsideAngle (-aCrossLine, aTrng1Edges[0], aTrng1Edges[1], anX, anY);
Standard_ASSERT_RAISE (aPosOutTrgn1 || aNegOutTrgn1,
"Failed to detect if shared vertex is regular or not");
if (aPosOutTrgn1 && aNegOutTrgn1)
{
return BRepExtrema_ElementFilter::NoCheck;
}
return (aPosOutTrgn0 || aPosOutTrgn1) && (aNegOutTrgn0 || aNegOutTrgn1) ?
BRepExtrema_ElementFilter::NoCheck : BRepExtrema_ElementFilter::Overlap;
}
}
//=======================================================================
//function : isRegularSharedEdge
//purpose :
//=======================================================================
BRepExtrema_ElementFilter::FilterResult BRepExtrema_SelfIntersection::isRegularSharedEdge (const BVH_Vec3d& theTrng0Vtxs0,
const BVH_Vec3d& theTrng0Vtxs1,
const BVH_Vec3d& theTrng0Vtxs2,
const BVH_Vec3d& theTrng1Vtxs2)
{
const BVH_Vec3d aSharedEdge = (theTrng0Vtxs1 - theTrng0Vtxs0).Normalized();
const BVH_Vec3d aUniqueEdges[] = { (theTrng0Vtxs2 - theTrng0Vtxs0).Normalized(),
(theTrng1Vtxs2 - theTrng0Vtxs0).Normalized() };
const BVH_Vec3d aTrng0Normal = BVH_Vec3d::Cross (aSharedEdge, aUniqueEdges[0]);
const BVH_Vec3d aTrng1Normal = BVH_Vec3d::Cross (aSharedEdge, aUniqueEdges[1]);
BVH_Vec3d aCrossLine = BVH_Vec3d::Cross (aTrng0Normal,
aTrng1Normal);
if (aCrossLine.SquareModulus() > Precision::SquareConfusion()) // non-coplanar case
{
return BRepExtrema_ElementFilter::NoCheck;
}
Standard_Integer anX;
Standard_Integer anY;
getProjectionAxes (aTrng0Normal, anX, anY);
return ccw (ZERO_VEC, aSharedEdge, aUniqueEdges[0], anX, anY) !=
ccw (ZERO_VEC, aSharedEdge, aUniqueEdges[1], anX, anY) ? BRepExtrema_ElementFilter::NoCheck
: BRepExtrema_ElementFilter::Overlap;
}
//=======================================================================
//function : PreCheckElements
//purpose :
//=======================================================================
BRepExtrema_ElementFilter::FilterResult BRepExtrema_SelfIntersection::PreCheckElements (const Standard_Integer theIndex1,
const Standard_Integer theIndex2)
{
if (myElementSet->GetFaceID (theIndex1) == myElementSet->GetFaceID (theIndex2))
{
return BRepExtrema_ElementFilter::NoCheck; // triangles are from the same face
}
BVH_Vec3d aTrng0Vtxs[3];
BVH_Vec3d aTrng1Vtxs[3];
myElementSet->GetVertices (theIndex1,
aTrng0Vtxs[0],
aTrng0Vtxs[1],
aTrng0Vtxs[2]);
myElementSet->GetVertices (theIndex2,
aTrng1Vtxs[0],
aTrng1Vtxs[1],
aTrng1Vtxs[2]);
std::vector<std::pair<Standard_Integer, Standard_Integer> > aSharedVtxs;
for (Standard_Integer aVertIdx1 = 0; aVertIdx1 < 3; ++aVertIdx1)
{
for (Standard_Integer aVertIdx2 = 0; aVertIdx2 < 3; ++aVertIdx2)
{
if ((aTrng0Vtxs[aVertIdx1] - aTrng1Vtxs[aVertIdx2]).SquareModulus() < Precision::SquareConfusion())
{
aSharedVtxs.push_back (std::pair<Standard_Integer, Standard_Integer> (aVertIdx1, aVertIdx2));
break; // go to next vertex of the 1st triangle
}
}
}
if (aSharedVtxs.size() == 2) // check shared edge
{
return isRegularSharedEdge (aTrng0Vtxs[aSharedVtxs[0].first],
aTrng0Vtxs[aSharedVtxs[1].first],
aTrng0Vtxs[3 - aSharedVtxs[0]. first - aSharedVtxs[1]. first],
aTrng1Vtxs[3 - aSharedVtxs[0].second - aSharedVtxs[1].second]);
}
else if (aSharedVtxs.size() == 1) // check shared vertex
{
std::swap (*aTrng0Vtxs, aTrng0Vtxs[aSharedVtxs.front(). first]);
std::swap (*aTrng1Vtxs, aTrng1Vtxs[aSharedVtxs.front().second]);
return isRegularSharedVertex (aTrng0Vtxs[0],
aTrng0Vtxs[1],
aTrng0Vtxs[2],
aTrng1Vtxs[1],
aTrng1Vtxs[2]);
}
return BRepExtrema_ElementFilter::DoCheck;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepExtrema_SelfIntersection::Perform()
{
if (!myIsInit || myOverlapTool.IsDone())
{
return;
}
myOverlapTool.SetElementFilter (this);
myOverlapTool.Perform (myTolerance);
}

View File

@@ -1,134 +0,0 @@
// Created on: 2015-04-26
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepExtrema_SelfIntersection_HeaderFile
#define _BRepExtrema_SelfIntersection_HeaderFile
#include <BRepExtrema_OverlapTool.hxx>
//! Tool class for detection of self-sections in the given shape.
//! This class is based on BRepExtrema_OverlapTool and thus uses
//! shape tessellation to detect incorrect mesh fragments (pairs
//! of overlapped triangles belonging to different faces). Thus,
//! a result depends critically on the quality of mesh generator
//! (e.g., BREP mesh is not always a good choice, because it can
//! contain gaps between adjacent face triangulations, which may
//! not share vertices on common edge; thus false overlap can be
//! detected). As a result, this tool can be used for relatively
//! fast approximated test which provides sub-set of potentially
//! overlapped faces.
class BRepExtrema_SelfIntersection : public BRepExtrema_ElementFilter
{
friend class BRepExtrema_OverlapTool;
public:
//! Creates unitialized self-intersection tool.
Standard_EXPORT BRepExtrema_SelfIntersection (const Standard_Real theTolerance = 0.0);
//! Creates self-intersection tool for the given shape.
Standard_EXPORT BRepExtrema_SelfIntersection (const TopoDS_Shape& theShape, const Standard_Real theTolerance = 0.0);
public:
//! Returns tolerance value used for self-intersection test.
Standard_Real Tolerance() const
{
return myTolerance;
}
//! Sets tolerance value used for self-intersection test.
void SetTolerance (const Standard_Real theTolerance)
{
myTolerance = theTolerance;
}
//! Loads shape for detection of self-intersections.
Standard_EXPORT Standard_Boolean LoadShape (const TopoDS_Shape& theShape);
//! Performs detection of self-intersections.
Standard_EXPORT void Perform();
//! True if the detection is completed.
Standard_Boolean IsDone() const
{
return myOverlapTool.IsDone();
}
//! Returns set of IDs of overlapped sub-shapes (started from 0).
const BRepExtrema_MapOfIntegerPackedMapOfInteger& OverlapElements() const
{
return myOverlapTool.OverlapSubShapes1();
}
//! Returns sub-shape from the shape for the given index (started from 0).
const TopoDS_Face& GetSubShape (const Standard_Integer theID) const
{
return myFaceList.Value (theID);
}
//! Returns set of all the face triangles of the shape.
const Handle(BRepExtrema_TriangleSet)& ElementSet() const
{
return myElementSet;
}
#ifdef OVERLAP_TOOL_OUTPUT_TRIANGLES
//! Returns set of overlapped mesh elements (only triangles).
const TColStd_PackedMapOfInteger& OverlapTriangles() const
{
return myOverlapTool.OverlapTriangles1();
}
#endif
protected:
//! Filter out correct adjacent mesh elements.
virtual BRepExtrema_ElementFilter::FilterResult PreCheckElements (const Standard_Integer theIndex1,
const Standard_Integer theIndex2);
//! Checks if the given triangles have only single common vertex.
BRepExtrema_ElementFilter::FilterResult isRegularSharedVertex (const BVH_Vec3d& theSharedVert,
const BVH_Vec3d& theTrng1Vtxs1,
const BVH_Vec3d& theTrng1Vtxs2,
const BVH_Vec3d& theTrng2Vtxs1,
const BVH_Vec3d& theTrng2Vtxs2);
//! Checks if the given triangles have only single common edge.
BRepExtrema_ElementFilter::FilterResult isRegularSharedEdge (const BVH_Vec3d& theTrng1Vtxs0,
const BVH_Vec3d& theTrng1Vtxs1,
const BVH_Vec3d& theTrng1Vtxs2,
const BVH_Vec3d& theTrng2Vtxs2);
private:
//! Self-intersection tolerance.
Standard_Real myTolerance;
//! Is the input shape inited?
Standard_Boolean myIsInit;
//! List of triangulated faces of the shape.
BRepExtrema_ShapeList myFaceList;
//! Set of all the face triangles of the shape.
Handle(BRepExtrema_TriangleSet) myElementSet;
//! Overlap tool used for self-intersection test.
BRepExtrema_OverlapTool myOverlapTool;
};
#endif // _BRepExtrema_SelfIntersection_HeaderFile

View File

@@ -20,15 +20,15 @@
//=======================================================================
//function : BRepExtrema_ShapeProximity
//purpose : Creates uninitialized proximity tool
//purpose : Creates empty proximity tool
//=======================================================================
BRepExtrema_ShapeProximity::BRepExtrema_ShapeProximity (const Standard_Real theTolerance)
: myTolerance (theTolerance),
myElementSet1 (new BRepExtrema_TriangleSet),
myElementSet2 (new BRepExtrema_TriangleSet)
: myTolerance (theTolerance),
myPrimitiveSet1 (new BRepExtrema_TriangleSet),
myPrimitiveSet2 (new BRepExtrema_TriangleSet)
{
// Should be initialized later
myIsInitS1 = myIsInitS2 = Standard_False;
myIsDone = myIsInitS1 = myIsInitS2 = Standard_False;
}
//=======================================================================
@@ -38,9 +38,9 @@ BRepExtrema_ShapeProximity::BRepExtrema_ShapeProximity (const Standard_Real theT
BRepExtrema_ShapeProximity::BRepExtrema_ShapeProximity (const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2,
const Standard_Real theTolerance)
: myTolerance (theTolerance),
myElementSet1 (new BRepExtrema_TriangleSet),
myElementSet2 (new BRepExtrema_TriangleSet)
: myTolerance (theTolerance),
myPrimitiveSet1 (new BRepExtrema_TriangleSet),
myPrimitiveSet2 (new BRepExtrema_TriangleSet)
{
LoadShape1 (theShape1);
LoadShape2 (theShape2);
@@ -59,9 +59,9 @@ Standard_Boolean BRepExtrema_ShapeProximity::LoadShape1 (const TopoDS_Shape& the
myFaceList1.Append (static_cast<const TopoDS_Face&> (anIter.Current()));
}
myOverlapTool.MarkDirty();
myIsDone = Standard_False;
return myIsInitS1 = myElementSet1->Init (myFaceList1);
return myIsInitS1 = myPrimitiveSet1->Init (myFaceList1);
}
//=======================================================================
@@ -77,24 +77,569 @@ Standard_Boolean BRepExtrema_ShapeProximity::LoadShape2 (const TopoDS_Shape& the
myFaceList2.Append (static_cast<const TopoDS_Face&> (anIter.Current()));
}
myOverlapTool.MarkDirty();
myIsDone = Standard_False;
return myIsInitS2 = myElementSet2->Init (myFaceList2);
return myIsInitS2 = myPrimitiveSet2->Init (myFaceList2);
}
namespace
{
//! Tool class to describe stack item in traverse function.
struct BRepExtrema_StackItem
{
Standard_Integer Node1;
Standard_Integer Node2;
BRepExtrema_StackItem (const Standard_Integer theNode1 = 0,
const Standard_Integer theNode2 = 0)
: Node1 (theNode1),
Node2 (theNode2)
{
//
}
};
//! Bounding triangular prism for specified triangle.
class BRepExtrema_BoundingPrism
{
public:
//! Vertices of the prism.
BVH_Vec3d Vertices[6];
//! Edges of the prism.
BVH_Vec3d Edges[3];
//! Normal to prism caps.
BVH_Vec3d Normal;
//! Normals to prism edges.
BVH_Vec3d EdgeNormals[3];
//! Is prism initialized?
Standard_Boolean IsInited;
public:
//! Creates uninitialized bounding prism.
BRepExtrema_BoundingPrism() : IsInited (Standard_False)
{
//
}
//! Creates new bounding prism for the given triangle.
BRepExtrema_BoundingPrism (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Real theDeflect)
{
Init (theVertex0,
theVertex1,
theVertex2,
theDeflect);
}
//! Calculates bounding prism for the given triangle.
void Init (const BVH_Vec3d& theVertex0,
const BVH_Vec3d& theVertex1,
const BVH_Vec3d& theVertex2,
const Standard_Real theDeflect)
{
Edges[0] = theVertex1 - theVertex0;
Edges[1] = theVertex2 - theVertex0;
Edges[2] = theVertex2 - theVertex1;
Normal = BVH_Vec3d::Cross (Edges[0], Edges[1]);
EdgeNormals[0] = BVH_Vec3d::Cross (Edges[0], Normal);
EdgeNormals[1] = BVH_Vec3d::Cross (Edges[1], Normal);
EdgeNormals[2] = BVH_Vec3d::Cross (Edges[2], Normal);
EdgeNormals[0] *= 1.0 / Max (EdgeNormals[0].Modulus(), Precision::Confusion());
EdgeNormals[1] *= 1.0 / Max (EdgeNormals[1].Modulus(), Precision::Confusion());
EdgeNormals[2] *= 1.0 / Max (EdgeNormals[2].Modulus(), Precision::Confusion());
const BVH_Vec3d aDirect01 = EdgeNormals[0] - EdgeNormals[1];
const BVH_Vec3d aDirect02 = EdgeNormals[0] + EdgeNormals[2];
const BVH_Vec3d aDirect12 = EdgeNormals[2] - EdgeNormals[1];
Vertices[0] = Vertices[3] = theVertex0 + aDirect01 * (theDeflect / aDirect01.Dot (EdgeNormals[0]));
Vertices[1] = Vertices[4] = theVertex1 + aDirect02 * (theDeflect / aDirect02.Dot (EdgeNormals[2]));
Vertices[2] = Vertices[5] = theVertex2 + aDirect12 * (theDeflect / aDirect12.Dot (EdgeNormals[2]));
const BVH_Vec3d aNormOffset = Normal * (theDeflect / Max (Normal.Modulus(), Precision::Confusion()));
for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx)
{
Vertices[aVertIdx + 0] += aNormOffset;
Vertices[aVertIdx + 3] -= aNormOffset;
}
IsInited = Standard_True;
}
//! Checks if two prisms are separated along the given axis.
Standard_Boolean Separated (const BRepExtrema_BoundingPrism& thePrism, const BVH_Vec3d& theAxis) const
{
Standard_Real aMin1 = DBL_MAX;
Standard_Real aMax1 = -DBL_MAX;
Standard_Real aMin2 = DBL_MAX;
Standard_Real aMax2 = -DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
{
const Standard_Real aProj1 = Vertices[aVertIdx].Dot (theAxis);
aMin1 = Min (aMin1, aProj1);
aMax1 = Max (aMax1, aProj1);
const Standard_Real aProj2 = thePrism.Vertices[aVertIdx].Dot (theAxis);
aMin2 = Min (aMin2, aProj2);
aMax2 = Max (aMax2, aProj2);
if (aMin1 <= aMax2 && aMax1 >= aMin2)
{
return Standard_False;
}
}
return aMin1 > aMax2 || aMax1 < aMin2;
}
};
// =======================================================================
// function : Separated
// purpose : Checks if triangles can be separated along the given axis
// (projects vertices on this axis and performs interval test)
// =======================================================================
inline Standard_Boolean SeparateTriangles (const BVH_Vec3d& theTrg1Vert0,
const BVH_Vec3d& theTrg1Vert1,
const BVH_Vec3d& theTrg1Vert2,
const BVH_Vec3d& theTrg2Vert0,
const BVH_Vec3d& theTrg2Vert1,
const BVH_Vec3d& theTrg2Vert2,
const BVH_Vec3d& theSplitAxis)
{
const Standard_Real aA1 = theTrg1Vert0.Dot (theSplitAxis);
const Standard_Real aB1 = theTrg1Vert1.Dot (theSplitAxis);
const Standard_Real aC1 = theTrg1Vert2.Dot (theSplitAxis);
const Standard_Real aA2 = theTrg2Vert0.Dot (theSplitAxis);
const Standard_Real aB2 = theTrg2Vert1.Dot (theSplitAxis);
const Standard_Real aC2 = theTrg2Vert2.Dot (theSplitAxis);
const Standard_Real aMin1 = Min (aA1, Min (aB1, aC1));
const Standard_Real aMax1 = Max (aA1, Max (aB1, aC1));
if (aMax1 < Min (aA2, Min (aB2, aC2)))
{
return Standard_True;
}
return aMin1 > Max (aA2, Max (aB2, aC2));
}
// =======================================================================
// function : TrianglesIntersected
// purpose : Checks if two triangles are intersected
// (test uses SAT - Separating Axis Theorem)
// =======================================================================
Standard_Boolean TrianglesIntersected (const BVH_Vec3d& theTrg1Vert0,
const BVH_Vec3d& theTrg1Vert1,
const BVH_Vec3d& theTrg1Vert2,
const BVH_Vec3d& theTrg2Vert0,
const BVH_Vec3d& theTrg2Vert1,
const BVH_Vec3d& theTrg2Vert2)
{
const BVH_Vec3d aEdges1[3] = { theTrg1Vert1 - theTrg1Vert0,
theTrg1Vert2 - theTrg1Vert0,
theTrg1Vert2 - theTrg1Vert1 };
const BVH_Vec3d aTrg1Normal = BVH_Vec3d::Cross (aEdges1[0], aEdges1[1]);
if (SeparateTriangles (theTrg1Vert0,
theTrg1Vert1,
theTrg1Vert2,
theTrg2Vert0,
theTrg2Vert1,
theTrg2Vert2,
aTrg1Normal))
{
return Standard_False;
}
const BVH_Vec3d aEdges2[3] = { theTrg2Vert1 - theTrg2Vert0,
theTrg2Vert2 - theTrg2Vert0,
theTrg2Vert2 - theTrg2Vert1 };
const BVH_Vec3d aTrg2Normal = BVH_Vec3d::Cross (aEdges2[0], aEdges2[1]);
if (SeparateTriangles (theTrg1Vert0,
theTrg1Vert1,
theTrg1Vert2,
theTrg2Vert0,
theTrg2Vert1,
theTrg2Vert2,
aTrg2Normal))
{
return Standard_False;
}
for (Standard_Integer anIdx1 = 0; anIdx1 < 3; ++anIdx1)
{
for (Standard_Integer anIdx2 = 0; anIdx2 < 3; ++anIdx2)
{
const BVH_Vec3d aSplitAxis = BVH_Vec3d::Cross (aEdges1[anIdx1], aEdges2[anIdx2]);
if (SeparateTriangles (theTrg1Vert0,
theTrg1Vert1,
theTrg1Vert2,
theTrg2Vert0,
theTrg2Vert1,
theTrg2Vert2,
aSplitAxis))
{
return Standard_False;
}
}
}
return Standard_True;
}
// =======================================================================
// function : PrismsIntersected
// purpose : Checks if two triangular prisms are intersected
// (test uses SAT - Separating Axis Theorem)
// =======================================================================
Standard_Boolean PrismsIntersected (const BRepExtrema_BoundingPrism& thePrism1,
const BRepExtrema_BoundingPrism& thePrism2)
{
if (thePrism1.Separated (thePrism2, thePrism1.Normal))
{
return Standard_False;
}
if (thePrism1.Separated (thePrism2, thePrism2.Normal))
{
return Standard_False;
}
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (thePrism1.Separated (thePrism2, thePrism1.EdgeNormals[anIdx]))
{
return Standard_False;
}
}
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (thePrism1.Separated (thePrism2, thePrism2.EdgeNormals[anIdx]))
{
return Standard_False;
}
}
for (Standard_Integer anIdx1 = 0; anIdx1 < 4; ++anIdx1)
{
const BVH_Vec3d& aEdge1 = (anIdx1 == 3) ? thePrism1.Normal : thePrism1.Edges[anIdx1];
for (Standard_Integer anIdx2 = 0; anIdx2 < 4; ++anIdx2)
{
const BVH_Vec3d& aEdge2 = (anIdx2 == 3) ? thePrism2.Normal : thePrism2.Edges[anIdx2];
if (thePrism1.Separated (thePrism2, BVH_Vec3d::Cross (aEdge1, aEdge2)))
{
return Standard_False;
}
}
}
return Standard_True;
}
// =======================================================================
// function : OverlapBoxes
// purpose : Checks if two boxes (AABBs) are overlapped
// =======================================================================
inline Standard_Boolean OverlapBoxes (const BVH_Vec3d& theBoxMin1,
const BVH_Vec3d& theBoxMax1,
const BVH_Vec3d& theBoxMin2,
const BVH_Vec3d& theBoxMax2,
const Standard_Real theTolerance)
{
// Check for overlap
return !(theBoxMin1.x() > theBoxMax2.x() + theTolerance ||
theBoxMax1.x() < theBoxMin2.x() - theTolerance ||
theBoxMin1.y() > theBoxMax2.y() + theTolerance ||
theBoxMax1.y() < theBoxMin2.y() - theTolerance ||
theBoxMin1.z() > theBoxMax2.z() + theTolerance ||
theBoxMax1.z() < theBoxMin2.z() - theTolerance);
}
//=======================================================================
//function : getSetOfFaces
//purpose :
//=======================================================================
TColStd_PackedMapOfInteger& getSetOfFaces (BRepExtrema_OverlappedSubShapes& theShapes,
const Standard_Integer theFaceIdx)
{
if (!theShapes.IsBound (theFaceIdx))
{
theShapes.Bind (theFaceIdx, TColStd_PackedMapOfInteger());
}
return theShapes.ChangeFind (theFaceIdx);
}
}
//=======================================================================
//function : IntersectLeavesExact
//purpose : Narrow-phase of overlap test (exact intersection)
//=======================================================================
void BRepExtrema_ShapeProximity::IntersectLeavesExact (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2)
{
for (Standard_Integer aTrgIdx1 = theLeaf1.y(); aTrgIdx1 <= theLeaf1.z(); ++aTrgIdx1)
{
const Standard_Integer aFaceIdx1 = myPrimitiveSet1->GetFaceID (aTrgIdx1);
BVH_Vec3d aTrg1Vert1;
BVH_Vec3d aTrg1Vert2;
BVH_Vec3d aTrg1Vert3;
myPrimitiveSet1->GetVertices (aTrgIdx1,
aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3);
const Standard_Boolean aIsInSet = myOverlapSubShapes1.IsBound (aFaceIdx1);
for (Standard_Integer aTrgIdx2 = theLeaf2.y(); aTrgIdx2 <= theLeaf2.z(); ++aTrgIdx2)
{
const Standard_Integer aFaceIdx2 = myPrimitiveSet2->GetFaceID (aTrgIdx2);
if (!aIsInSet || !myOverlapSubShapes1.Find (aFaceIdx1).Contains (aFaceIdx2))
{
BVH_Vec3d aTrg2Vert1;
BVH_Vec3d aTrg2Vert2;
BVH_Vec3d aTrg2Vert3;
myPrimitiveSet2->GetVertices (aTrgIdx2, aTrg2Vert1, aTrg2Vert2, aTrg2Vert3);
if (TrianglesIntersected (aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3,
aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3))
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
}
}
}
}
}
//=======================================================================
//function : IntersectLeavesToler
//purpose : Narrow-phase of overlap test (with non-zero tolerance)
//=======================================================================
void BRepExtrema_ShapeProximity::IntersectLeavesToler (const BVH_Vec4i& theLeaf1,
const BVH_Vec4i& theLeaf2)
{
for (Standard_Integer aTrgIdx1 = theLeaf1.y(); aTrgIdx1 <= theLeaf1.z(); ++aTrgIdx1)
{
const Standard_Integer aFaceIdx1 = myPrimitiveSet1->GetFaceID (aTrgIdx1);
BVH_Vec3d aTrg1Vert1;
BVH_Vec3d aTrg1Vert2;
BVH_Vec3d aTrg1Vert3;
myPrimitiveSet1->GetVertices (aTrgIdx1,
aTrg1Vert1,
aTrg1Vert2,
aTrg1Vert3);
BRepExtrema_BoundingPrism aPrism1; // not initialized
const Standard_Boolean aIsInSet = myOverlapSubShapes1.IsBound (aFaceIdx1);
for (Standard_Integer aTrgIdx2 = theLeaf2.y(); aTrgIdx2 <= theLeaf2.z(); ++aTrgIdx2)
{
const Standard_Integer aFaceIdx2 = myPrimitiveSet2->GetFaceID (aTrgIdx2);
if (!aIsInSet || !myOverlapSubShapes1.Find (aFaceIdx1).Contains (aFaceIdx2))
{
if (!aPrism1.IsInited)
{
aPrism1.Init (aTrg1Vert1, aTrg1Vert2, aTrg1Vert3, myTolerance);
}
BVH_Vec3d aTrg2Vert1;
BVH_Vec3d aTrg2Vert2;
BVH_Vec3d aTrg2Vert3;
myPrimitiveSet2->GetVertices (aTrgIdx2,
aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3);
BRepExtrema_BoundingPrism aPrism2 (aTrg2Vert1,
aTrg2Vert2,
aTrg2Vert3,
myTolerance);
if (PrismsIntersected (aPrism1, aPrism2))
{
getSetOfFaces (myOverlapSubShapes1, aFaceIdx1).Add (aFaceIdx2);
getSetOfFaces (myOverlapSubShapes2, aFaceIdx2).Add (aFaceIdx1);
}
}
}
}
}
//=======================================================================
//function : Perform
//purpose : Performs search of overlapped faces
//purpose : Performs search for overlapped faces
//=======================================================================
void BRepExtrema_ShapeProximity::Perform()
{
if (!myIsInitS1 || !myIsInitS2 || myOverlapTool.IsDone())
if (myIsDone || !myIsInitS1 || !myIsInitS2)
{
return;
}
myOverlapTool.LoadTriangleSets (myElementSet1,
myElementSet2);
BRepExtrema_StackItem aStack[96];
myOverlapTool.Perform (myTolerance);
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH1 = myPrimitiveSet1->BVH();
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH2 = myPrimitiveSet2->BVH();
if (aBVH1.IsNull() || aBVH2.IsNull())
{
return;
}
BRepExtrema_StackItem aNodes; // current pair of nodes
Standard_Integer aHead = -1; // stack head position
for (;;)
{
BVH_Vec4i aNodeData1 = aBVH1->NodeInfoBuffer()[aNodes.Node1];
BVH_Vec4i aNodeData2 = aBVH2->NodeInfoBuffer()[aNodes.Node2];
if (aNodeData1.x() != 0 && aNodeData2.x() != 0) // leaves
{
if (myTolerance == 0.0)
{
IntersectLeavesExact (aNodeData1, aNodeData2);
}
else
{
IntersectLeavesToler (aNodeData1, aNodeData2);
}
if (aHead < 0)
break;
aNodes = aStack[aHead--];
}
else
{
BRepExtrema_StackItem aPairsToProcess[4];
Standard_Integer aNbPairs = 0;
if (aNodeData1.x() == 0) // inner node
{
const BVH_Vec3d& aMinPntLft1 = aBVH1->MinPoint (aNodeData1.y());
const BVH_Vec3d& aMaxPntLft1 = aBVH1->MaxPoint (aNodeData1.y());
const BVH_Vec3d& aMinPntRgh1 = aBVH1->MinPoint (aNodeData1.z());
const BVH_Vec3d& aMaxPntRgh1 = aBVH1->MaxPoint (aNodeData1.z());
if (aNodeData2.x() == 0) // inner node
{
const BVH_Vec3d& aMinPntLft2 = aBVH2->MinPoint (aNodeData2.y());
const BVH_Vec3d& aMaxPntLft2 = aBVH2->MaxPoint (aNodeData2.y());
const BVH_Vec3d& aMinPntRgh2 = aBVH2->MinPoint (aNodeData2.z());
const BVH_Vec3d& aMaxPntRgh2 = aBVH2->MaxPoint (aNodeData2.z());
if (OverlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntLft2, aMaxPntLft2, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodeData2.y());
}
if (OverlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntRgh2, aMaxPntRgh2, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodeData2.z());
}
if (OverlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntLft2, aMaxPntLft2, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodeData2.y());
}
if (OverlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntRgh2, aMaxPntRgh2, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodeData2.z());
}
}
else
{
const BVH_Vec3d& aMinPntLeaf = aBVH2->MinPoint (aNodes.Node2);
const BVH_Vec3d& aMaxPntLeaf = aBVH2->MaxPoint (aNodes.Node2);
if (OverlapBoxes (aMinPntLft1, aMaxPntLft1, aMinPntLeaf, aMaxPntLeaf, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.y(), aNodes.Node2);
}
if (OverlapBoxes (aMinPntRgh1, aMaxPntRgh1, aMinPntLeaf, aMaxPntLeaf, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodeData1.z(), aNodes.Node2);
}
}
}
else
{
const BVH_Vec3d& aMinPntLeaf = aBVH1->MinPoint (aNodes.Node1);
const BVH_Vec3d& aMaxPntLeaf = aBVH1->MaxPoint (aNodes.Node1);
const BVH_Vec3d& aMinPntLft2 = aBVH2->MinPoint (aNodeData2.y());
const BVH_Vec3d& aMaxPntLft2 = aBVH2->MaxPoint (aNodeData2.y());
const BVH_Vec3d& aMinPntRgh2 = aBVH2->MinPoint (aNodeData2.z());
const BVH_Vec3d& aMaxPntRgh2 = aBVH2->MaxPoint (aNodeData2.z());
if (OverlapBoxes (aMinPntLft2, aMaxPntLft2, aMinPntLeaf, aMaxPntLeaf, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodes.Node1, aNodeData2.y());
}
if (OverlapBoxes (aMinPntRgh2, aMaxPntRgh2, aMinPntLeaf, aMaxPntLeaf, myTolerance))
{
aPairsToProcess[aNbPairs++] = BRepExtrema_StackItem (aNodes.Node1, aNodeData2.z());
}
}
if (aNbPairs > 0)
{
aNodes = aPairsToProcess[0];
for (Standard_Integer anIdx = 1; anIdx < aNbPairs; ++anIdx)
{
aStack[++aHead] = aPairsToProcess[anIdx];
}
}
else
{
if (aHead < 0)
break;
aNodes = aStack[aHead--];
}
}
}
myIsDone = Standard_True;
}

View File

@@ -17,11 +17,12 @@
#define _BRepExtrema_ShapeProximity_HeaderFile
#include <BVH_Geometry.hxx>
#include <NCollection_DataMap.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <BRepExtrema_TriangleSet.hxx>
#include <BRepExtrema_OverlapTool.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <NCollection_DataMap.hxx>
//! Set of overlapped sub-shapes.
typedef NCollection_DataMap<Standard_Integer, TColStd_PackedMapOfInteger > BRepExtrema_OverlappedSubShapes;
//! Tool class for shape proximity detection.
//! For two given shapes and given tolerance (offset from the mesh) the algorithm allows
@@ -37,7 +38,7 @@
//! on distance less than the given tolerance from each other.
class BRepExtrema_ShapeProximity
{
public:
public:
//! Creates empty proximity tool.
Standard_EXPORT BRepExtrema_ShapeProximity (const Standard_Real theTolerance = 0.0);
@@ -67,50 +68,58 @@ public:
//! Loads 2nd shape into proximity tool.
Standard_EXPORT Standard_Boolean LoadShape2 (const TopoDS_Shape& theShape2);
//! Performs search of overlapped faces.
//! Performs search for overlapped faces.
Standard_EXPORT void Perform();
//! True if the search is completed.
Standard_Boolean IsDone() const
{
return myOverlapTool.IsDone();
return myIsDone;
}
//! Returns set of IDs of overlapped faces of 1st shape (started from 0).
const BRepExtrema_MapOfIntegerPackedMapOfInteger& OverlapSubShapes1() const
//! Returns set of all the face triangles of the 1st shape.
const NCollection_Handle<BRepExtrema_TriangleSet>& PrimitiveSet1() const
{
return myOverlapTool.OverlapSubShapes1();
return myPrimitiveSet1;
}
//! Returns set of IDs of overlapped faces of 2nd shape (started from 0).
const BRepExtrema_MapOfIntegerPackedMapOfInteger& OverlapSubShapes2() const
//! Returns set of all the face triangles of the 2nd shape.
const NCollection_Handle<BRepExtrema_TriangleSet>& PrimitiveSet2() const
{
return myOverlapTool.OverlapSubShapes2();
return myPrimitiveSet2;
}
//! Returns sub-shape from 1st shape with the given index (started from 0).
//! Returns set of IDs of overlapped faces of 1st shape.
const BRepExtrema_OverlappedSubShapes& OverlapSubShapes1() const
{
return myOverlapSubShapes1;
}
//! Returns set of IDs of overlapped faces of 2nd shape.
const BRepExtrema_OverlappedSubShapes& OverlapSubShapes2() const
{
return myOverlapSubShapes2;
}
//! Returns sub-shape from 1st shape with the given index.
const TopoDS_Face& GetSubShape1 (const Standard_Integer theID) const
{
return myFaceList1.Value (theID);
}
//! Returns sub-shape from 1st shape with the given index (started from 0).
//! Returns sub-shape from 1st shape with the given index.
const TopoDS_Face& GetSubShape2 (const Standard_Integer theID) const
{
return myFaceList2.Value (theID);
}
//! Returns set of all the face triangles of the 1st shape.
const Handle(BRepExtrema_TriangleSet)& ElementSet1() const
{
return myElementSet1;
}
protected:
//! Returns set of all the face triangles of the 2nd shape.
const Handle(BRepExtrema_TriangleSet)& ElementSet2() const
{
return myElementSet2;
}
//! Performs narrow-phase of overlap test (exact intersection).
void IntersectLeavesExact (const BVH_Vec4i& theLeaf1, const BVH_Vec4i& theLeaf2);
//! Performs narrow-phase of overlap test (intersection with non-zero tolerance).
void IntersectLeavesToler (const BVH_Vec4i& theLeaf1, const BVH_Vec4i& theLeaf2);
private:
@@ -128,12 +137,17 @@ private:
BRepExtrema_ShapeList myFaceList2;
//! Set of all the face triangles of the 1st shape.
Handle(BRepExtrema_TriangleSet) myElementSet1;
NCollection_Handle<BRepExtrema_TriangleSet> myPrimitiveSet1;
//! Set of all the face triangles of the 2nd shape.
Handle(BRepExtrema_TriangleSet) myElementSet2;
NCollection_Handle<BRepExtrema_TriangleSet> myPrimitiveSet2;
//! Overlap tool used for intersection/overlap test.
BRepExtrema_OverlapTool myOverlapTool;
//! Set of overlapped faces of 1st shape.
BRepExtrema_OverlappedSubShapes myOverlapSubShapes1;
//! Set of overlapped faces of 2nd shape.
BRepExtrema_OverlappedSubShapes myOverlapSubShapes2;
//! Is overlap test completed?
Standard_Boolean myIsDone;
};

View File

@@ -21,9 +21,6 @@
#include <Poly_Triangulation.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
IMPLEMENT_STANDARD_HANDLE (BRepExtrema_TriangleSet, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BRepExtrema_TriangleSet, Standard_Transient)
//=======================================================================
//function : BRepExtrema_TriangleSet
//purpose : Creates empty triangle set
@@ -227,4 +224,3 @@ Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& the
return Standard_True;
}

View File

@@ -17,13 +17,14 @@
#define _BRepExtrema_TriangleSet_HeaderFile
#include <TopoDS_Face.hxx>
#include <BVH_PrimitiveSet.hxx>
//! List of shapes and their IDs for collision detection.
typedef NCollection_Vector<TopoDS_Face> BRepExtrema_ShapeList;
//! Triangle set corresponding to specific face.
class BRepExtrema_TriangleSet : public BVH_PrimitiveSet<Standard_Real, 3>, public Standard_Transient
class BRepExtrema_TriangleSet : public BVH_PrimitiveSet<Standard_Real, 3>
{
public:
@@ -78,12 +79,6 @@ protected:
//! Array of vertex coordinates.
BVH_Array3d myVertexArray;
public:
DEFINE_STANDARD_RTTI(BRepExtrema_TriangleSet)
};
DEFINE_STANDARD_HANDLE (BRepExtrema_TriangleSet, Standard_Transient)
#endif // _BRepExtrema_TriangleSet_HeaderFile

View File

@@ -19,11 +19,5 @@ BRepExtrema_SolutionElem.hxx
BRepExtrema_SupportType.hxx
BRepExtrema_TriangleSet.hxx
BRepExtrema_TriangleSet.cxx
BRepExtrema_OverlapTool.hxx
BRepExtrema_OverlapTool.cxx
BRepExtrema_ElementFilter.hxx
BRepExtrema_ShapeProximity.hxx
BRepExtrema_ShapeProximity.cxx
BRepExtrema_SelfIntersection.hxx
BRepExtrema_SelfIntersection.cxx
BRepExtrema_MapOfIntegerPackedMapOfInteger.hxx

View File

@@ -900,9 +900,6 @@ void BRepFill_OffsetWire::PerformWithBiLo
// MapNodeVertex,VE);
}
if (myJoinType == GeomAbs_Intersection)
StartOnEdge = EndOnEdge = 0;
//---------------------------------------------
// Construction of geometries.
//---------------------------------------------
@@ -915,7 +912,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
// Construction of vertices on edges parallel to the spine.
//-----------------------------------------------------------
Trim.IntersectWith(E [0], E [1], myJoinType, Params);
Trim.IntersectWith(E [0], E [1], Params);
for (Standard_Integer s = 1; s <= Params.Length(); s++) {
TopoDS_Vertex VC;
@@ -2235,10 +2232,10 @@ void TrimEdge (const TopoDS_Edge& E,
// otherwise preserve only one of its representations.
//----------------------------------------------------------
if (!BRep_Tool::Degenerated(E)) {
Standard_Real aParTol = 2.0 * Precision::PConfusion();
for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) ||
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= aParTol) {
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) {
if(k+1 == TheVer.Length()) {
StoreInMap(TheVer(k), TheVer(k+1), MapVV);

View File

@@ -26,8 +26,7 @@ uses
Curve from Geom2d,
Geometry from Geom2d,
SequenceOfPnt from TColgp,
Curve from Geom2dAdaptor,
JoinType from GeomAbs
Curve from Geom2dAdaptor
is
Create
@@ -40,7 +39,6 @@ is
IntersectWith( me : in out;
Edge1 , Edge2 : Edge from TopoDS;
theJoinType : JoinType from GeomAbs;
Params : in out SequenceOfPnt from TColgp)
is static;

View File

@@ -303,9 +303,8 @@ static void EvalParametersBis(const Geom2dAdaptor_Curve& Bis,
//=======================================================================
void BRepFill_TrimEdgeTool::IntersectWith(const TopoDS_Edge& Edge1,
const TopoDS_Edge& Edge2,
const GeomAbs_JoinType theJoinType,
TColgp_SequenceOfPnt& Params)
const TopoDS_Edge& Edge2,
TColgp_SequenceOfPnt& Params)
{
Params.Clear();
@@ -554,23 +553,6 @@ void BRepFill_TrimEdgeTool::IntersectWith(const TopoDS_Edge& Edge1,
Points2.Remove(Params.Length()+1, Points2.Length());
}
NbPoints = Params.Length();
if (NbPoints > 0 && theJoinType == GeomAbs_Intersection)
{
//Remove all vertices with non-minimal parameter
Standard_Integer imin = 1;
for (i = 2; i <= NbPoints; i++)
if (Params(i).X() < Params(imin).X())
imin = i;
gp_Pnt Pnt1 = Params(imin);
gp_Pnt Pnt2 = Points2(imin);
Params.Clear();
Points2.Clear();
Params.Append(Pnt1);
Points2.Append(Pnt2);
}
NbPoints = Params.Length();
for ( i = 1; i <= NbPoints; i++) {
PSeq = Params(i);

View File

@@ -26,7 +26,6 @@
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomProjLib.hxx>
@@ -57,12 +56,12 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
const Standard_Real theFirst,
const Standard_Real theLast)
:
myCurve(theC3D),
myPCurve(theC2D),
mySurf(theSurf),
myFirst(theFirst),
myLast(theLast)
{
myCurve = new GeomAdaptor_HCurve(theC3D);
myPCurve = new Geom2dAdaptor_HCurve(theC2D);
mySurf = new GeomAdaptor_HSurface(theSurf);
}
//
virtual Standard_Integer NbVariables() const {
@@ -161,9 +160,9 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
return ((myFirst <= theParam) && (theParam <= myLast));
}
Handle(GeomAdaptor_HCurve) myCurve;
Handle(Geom2dAdaptor_HCurve) myPCurve;
Handle(GeomAdaptor_HSurface) mySurf;
Handle(Geom_Curve) myCurve;
Handle(Geom2d_Curve) myPCurve;
Handle(Geom_Surface) mySurf;
Standard_Real myFirst;
Standard_Real myLast;
};

View File

@@ -773,7 +773,7 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
Standard_Real cl = C->LastParameter();
Standard_Real epsilon = Precision::PConfusion();
Standard_Boolean periodic = C->IsPeriodic();
GeomAdaptor_Curve aCA(C);
TopoDS_Vertex V1,V2;
if (periodic) {
@@ -813,15 +813,14 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
gp_Pnt P1,P2;
if (!p1inf) P1 = aCA.Value(p1);
if (!p2inf) P2 = aCA.Value(p2);
if (!p1inf) P1 = C->Value(p1);
if (!p2inf) P2 = C->Value(p2);
Standard_Real preci = BRepLib::Precision();
BRep_Builder B;
// check for closed curve
Standard_Boolean closed = Standard_False;
Standard_Boolean degenerated = Standard_False;
if (!p1inf && !p2inf)
closed = (P1.Distance(P2) <= preci);
@@ -837,19 +836,13 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
V2 = V1;
else {
if (!V1.IsSame(V2)) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
}
else if (P1.Distance(BRep_Tool::Pnt(V1)) >
Max(preci,BRep_Tool::Tolerance(V1))) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
}
else
{
gp_Pnt PM = aCA.Value((p1+p2)/2);
if (P1.Distance(PM) < preci)
degenerated = Standard_True;
Max(preci,BRep_Tool::Tolerance(V1))) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
}
}
}
@@ -905,7 +898,6 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
B.Add(E,V2);
}
B.Range(E,p1,p2);
B.Degenerated(E, degenerated);
myError = BRepLib_EdgeDone;
Done();

View File

@@ -112,10 +112,8 @@
#include <Geom_Plane.hxx>
#include <IntTools_FClass2d.hxx>
#include <BRepLib_FindSurface.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <NCollection_List.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
// POP for NT
#include <stdio.h>
@@ -240,13 +238,11 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
}
#endif
//---------------------------------------------------------------------
static void UpdateTolerance ( TopoDS_Shape& myShape,
const TopTools_IndexedMapOfShape& myFaces);
static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList);
//---------------------------------------------------------------------
//
static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
const TopoDS_Edge& E,
Standard_Real& U)
@@ -463,10 +459,6 @@ static void FillContours(const TopoDS_Shape& aShape,
}
}
//
//-----------------------------------------------------------------------
//
//=======================================================================
//function : BRepOffset_MakeOffset
//purpose :
@@ -679,10 +671,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
//------------------------------------------
// Construction of myShape without caps.
//------------------------------------------
if(!myFaces.IsEmpty())
{
RemoveCorks (myShape,myFaces);
}
RemoveCorks (myShape,myFaces);
if (! IsConnectedShell(myShape))
Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
@@ -1853,11 +1842,6 @@ void BRepOffset_MakeOffset::UpdateFaceOffset()
void BRepOffset_MakeOffset::CorrectConicalFaces()
{
if(myOffsetShape.IsNull())
{
return;
}
//
TopTools_SequenceOfShape Cones;
TopTools_SequenceOfShape Circs;
TopTools_SequenceOfShape Seams;
@@ -1925,7 +1909,6 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
BRep_Builder BB;
TopLoc_Location L;
Standard_Boolean IsModified = Standard_False;
for (; Cone.More(); Cone.Next() ) {
gp_Sphere theSphere;
Handle(Geom_SphericalSurface) aSphSurf;
@@ -2172,108 +2155,40 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
TopoDS_Shape theShell = Explo.Current();
theShell.Free( Standard_True );
BB.Add( theShell, NewSphericalFace );
IsModified = Standard_True;
if(!theShell.Closed())
{
if(BRep_Tool::IsClosed(theShell))
{
theShell.Closed(Standard_True);
}
}
}
//
if(!IsModified)
{
return;
}
//
if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
{
//Explo.Init( myOffsetShape, TopAbs_SHELL );
//if (Explo.More()) {
// TopoDS_Shape theShell = Explo.Current();
// theShell.Closed( Standard_True );
//}
Explo.Init( myOffsetShape, TopAbs_SHELL );
if (Explo.More()) {
TopoDS_Shape theShell = Explo.Current();
theShell.Closed( Standard_True );
}
Standard_Integer NbShell = 0;
TopoDS_Compound NC;
TopoDS_Shape S1;
BB.MakeCompound (NC);
TopoDS_Solid Sol;
BB.MakeSolid(Sol);
Sol.Closed(Standard_True);
for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
TopoDS_Shell Sh = TopoDS::Shell(Explo.Current());
//if (myThickening && myOffset > 0.)
// Sh.Reverse();
const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
NbShell++;
if (Sh.Closed()) {
BB.Add(Sol,Sh);
TopoDS_Solid Sol;
BB.MakeSolid (Sol);
BB.Add (Sol,Sh);
Sol.Closed(Standard_True);
BB.Add (NC,Sol);
if (NbShell == 1) S1 = Sol;
}
else {
BB.Add (NC,Sh);
if(NbShell == 1)
{
S1 = Sh;
}
if (NbShell == 1) S1 = Sh;
}
}
TopoDS_Iterator anIt(Sol);
Standard_Boolean SolIsNull = !anIt.More();
//Checking solid
if(!SolIsNull)
{
Standard_Integer nbs = 0;
while(anIt.More()) {anIt.Next(); ++nbs;}
if(nbs > 1)
{
BRepCheck_Analyzer aCheck(Sol, Standard_False);
if(!aCheck.IsValid())
{
TopTools_ListOfShape aSolList;
CorrectSolid(Sol, aSolList);
if(!aSolList.IsEmpty())
{
BB.Add(NC, Sol);
TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
for(; aSLIt.More(); aSLIt.Next())
{
BB.Add(NC, aSLIt.Value());
}
SolIsNull = Standard_True;
}
}
}
}
//
anIt.Initialize(NC);
Standard_Boolean NCIsNull = !anIt.More();
if((!SolIsNull) && (!NCIsNull))
{
BB.Add(NC, Sol);
myOffsetShape = NC;
}
else if(SolIsNull && (!NCIsNull))
{
if (NbShell == 1)
{
myOffsetShape = S1;
}
else
{
myOffsetShape = NC;
}
}
else if((!SolIsNull) && NCIsNull)
{
myOffsetShape = Sol;
}
else
{
myOffsetShape = NC;
}
if (NbShell == 1) myOffsetShape = S1;
else myOffsetShape = NC;
}
}
@@ -2873,30 +2788,16 @@ void BRepOffset_MakeOffset::MakeShells ()
}
if (myThickening)
{
TopExp_Explorer Explo(myShape, TopAbs_FACE);
for (; Explo.More(); Explo.Next())
Glue.Add(Explo.Current());
{
TopExp_Explorer Explo(myShape, TopAbs_FACE);
for (; Explo.More(); Explo.Next())
Glue.Add(Explo.Current());
for (it.Initialize(myWalls); it.More(); it.Next())
Glue.Add(it.Value());
}
for (it.Initialize(myWalls); it.More(); it.Next())
Glue.Add(it.Value());
}
myOffsetShape = Glue.Shells();
//
//Set correct value for closed flag
TopExp_Explorer Explo(myOffsetShape, TopAbs_SHELL);
for(; Explo.More(); Explo.Next())
{
TopoDS_Shape aS = Explo.Current();
if(!aS.Closed())
{
if(BRep_Tool::IsClosed(aS))
{
aS.Closed(Standard_True);
}
}
}
}
//=======================================================================
@@ -2920,79 +2821,26 @@ void BRepOffset_MakeOffset::MakeSolid ()
TopoDS_Shape S1;
B.MakeCompound (NC);
TopoDS_Solid Sol;
B.MakeSolid(Sol);
Sol.Closed(Standard_True);
Standard_Boolean aMakeSolid = (myShape.ShapeType() == TopAbs_SOLID) || myThickening;
for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
if (myThickening && myOffset > 0.)
Sh.Reverse();
NbShell++;
if (Sh.Closed() && aMakeSolid) {
B.Add(Sol,Sh);
if (Sh.Closed()) {
TopoDS_Solid Sol;
B.MakeSolid (Sol);
B.Add (Sol,Sh);
Sol.Closed(Standard_True);
B.Add (NC,Sol);
if (NbShell == 1) S1 = Sol;
}
else {
B.Add (NC,Sh);
if(NbShell == 1)
{
S1 = Sh;
}
if (NbShell == 1) S1 = Sh;
}
}
TopoDS_Iterator anIt(Sol);
Standard_Boolean SolIsNull = !anIt.More();
//Checking solid
if(!SolIsNull)
{
Standard_Integer nbs = 0;
while(anIt.More()) {anIt.Next(); ++nbs;}
if(nbs > 1)
{
BRepCheck_Analyzer aCheck(Sol, Standard_False);
if(!aCheck.IsValid())
{
TopTools_ListOfShape aSolList;
CorrectSolid(Sol, aSolList);
if(!aSolList.IsEmpty())
{
B.Add(NC, Sol);
TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
for(; aSLIt.More(); aSLIt.Next())
{
B.Add(NC, aSLIt.Value());
}
SolIsNull = Standard_True;
}
}
}
}
anIt.Initialize(NC);
Standard_Boolean NCIsNull = !anIt.More();
if((!SolIsNull) && (!NCIsNull))
{
B.Add(NC, Sol);
myOffsetShape = NC;
}
else if(SolIsNull && (!NCIsNull))
{
if (NbShell == 1)
{
myOffsetShape = S1;
}
else
{
myOffsetShape = NC;
}
}
else if((!SolIsNull) && NCIsNull)
{
myOffsetShape = Sol;
}
else
{
myOffsetShape = NC;
}
if (NbShell == 1) myOffsetShape = S1;
else myOffsetShape = NC;
}
//=======================================================================
@@ -3014,7 +2862,7 @@ void BRepOffset_MakeOffset::SelectShells ()
const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
if (LA.Extent() < 2) {
if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
FreeEdges.Add(E);
FreeEdges.Add(E);
}
}
}
@@ -3261,8 +3109,8 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
//purpose :
//=======================================================================
void UpdateTolerance (TopoDS_Shape& S,
const TopTools_IndexedMapOfShape& Faces)
static void UpdateTolerance (TopoDS_Shape& S,
const TopTools_IndexedMapOfShape& Faces)
{
BRep_Builder B;
TopTools_MapOfShape View;
@@ -3304,78 +3152,3 @@ void UpdateTolerance (TopoDS_Shape& S,
}
}
//=======================================================================
//function : CorrectSolid
//purpose :
//=======================================================================
void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
{
BRep_Builder aBB;
TopoDS_Shape anOuterShell;
NCollection_List<Standard_Real> aVols;
Standard_Real aVolMax = 0., anOuterVol = 0.;
TopoDS_Iterator anIt(theSol);
for(; anIt.More(); anIt.Next())
{
const TopoDS_Shape& aSh = anIt.Value();
GProp_GProps aVProps;
BRepGProp::VolumeProperties(aSh, aVProps, Standard_True);
if(Abs(aVProps.Mass()) > aVolMax)
{
anOuterVol = aVProps.Mass();
aVolMax = Abs(anOuterVol);
anOuterShell = aSh;
}
aVols.Append(aVProps.Mass());
}
//
if(anOuterVol < 0.)
{
anOuterShell.Reverse();
}
TopoDS_Solid aNewSol;
aBB.MakeSolid(aNewSol);
aNewSol.Closed(Standard_True);
aBB.Add(aNewSol, anOuterShell);
BRepClass3d_SolidClassifier aSolClass(aNewSol);
//
anIt.Initialize(theSol);
NCollection_List<Standard_Real>::Iterator aVIt(aVols);
for(; anIt.More(); anIt.Next(), aVIt.Next())
{
TopoDS_Shell aSh = TopoDS::Shell(anIt.Value());
if(aSh.IsSame(anOuterShell))
{
continue;
}
else
{
TopExp_Explorer aVExp(aSh, TopAbs_VERTEX);
const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current());
gp_Pnt aP = BRep_Tool::Pnt(aV);
aSolClass.Perform(aP, BRep_Tool::Tolerance(aV));
if(aSolClass.State() == TopAbs_IN)
{
if(aVIt.Value() > 0.)
{
aSh.Reverse();
}
aBB.Add(aNewSol, aSh);
}
else
{
if(aVIt.Value() < 0.)
{
aSh.Reverse();
}
TopoDS_Solid aSol;
aBB.MakeSolid(aSol);
aSol.Closed(Standard_True);
aBB.Add(aSol, aSh);
theSolList.Append(aSol);
}
}
}
theSol = aNewSol;
}

View File

@@ -21,10 +21,8 @@
#include <BRepExtrema_Poly.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepExtrema_ShapeProximity.hxx>
#include <BRepExtrema_SelfIntersection.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS_Compound.hxx>
#include <Draw.hxx>
@@ -235,18 +233,18 @@ static int ShapeProximity (Draw_Interpretor& theDI, Standard_Integer theNbArgs,
if (aProfile)
{
theDI << "Number of primitives in shape 1: " << aTool.ElementSet1()->Size() << "\n";
theDI << "Number of primitives in shape 2: " << aTool.ElementSet2()->Size() << "\n";
theDI << "Number of primitives in shape 1: " << aTool.PrimitiveSet1()->Size() << "\n";
theDI << "Number of primitives in shape 2: " << aTool.PrimitiveSet2()->Size() << "\n";
theDI << "Building data structures: " << aInitTime << "\n";
theDI << "Executing proximity test: " << aWorkTime << "\n";
}
TopoDS_Builder aCompBuilder;
TopoDS_Builder aCompBuilder;
TopoDS_Compound aFaceCompound1;
aCompBuilder.MakeCompound (aFaceCompound1);
for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt1 (aTool.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aTool.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[1]) + "_" + (anIt1.Key() + 1);
@@ -260,7 +258,7 @@ static int ShapeProximity (Draw_Interpretor& theDI, Standard_Integer theNbArgs,
TopoDS_Compound aFaceCompound2;
aCompBuilder.MakeCompound (aFaceCompound2);
for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt2 (aTool.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aTool.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[2]) + "_" + (anIt2.Key() + 1);
@@ -277,123 +275,6 @@ static int ShapeProximity (Draw_Interpretor& theDI, Standard_Integer theNbArgs,
return 0;
}
//==============================================================================
//function : ShapeSelfIntersection
//purpose :
//==============================================================================
static int ShapeSelfIntersection (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgs)
{
if (theNbArgs < 2 || theNbArgs > 5)
{
std::cout << "Usage: " << theArgs[0] <<
" Shape [-tol <value>] [-profile]" << std::endl;
return 1;
}
TopoDS_Shape aShape = DBRep::Get (theArgs[1]);
if (aShape.IsNull())
{
std::cout << "Error: Failed to find specified shape" << std::endl;
return 1;
}
Standard_Real aTolerance = 0.0;
Standard_Boolean aToProfile = Standard_False;
for (Standard_Integer anArgIdx = 2; anArgIdx < theNbArgs; ++anArgIdx)
{
TCollection_AsciiString aFlag (theArgs[anArgIdx]);
aFlag.LowerCase();
if (aFlag == "-tol")
{
if (++anArgIdx >= theNbArgs)
{
std::cout << "Error: wrong syntax at argument '" << aFlag << std::endl;
return 1;
}
const Standard_Real aValue = Draw::Atof (theArgs[anArgIdx]);
if (aValue < 0.0)
{
std::cout << "Error: Tolerance value should be non-negative" << std::endl;
return 1;
}
else
{
aTolerance = aValue;
}
}
if (aFlag == "-profile")
{
aToProfile = Standard_True;
}
}
OSD_Timer aTimer;
Standard_Real aInitTime = 0.0;
Standard_Real aWorkTime = 0.0;
if (aToProfile)
{
aTimer.Start();
}
BRepExtrema_SelfIntersection aTool (aShape, aTolerance);
if (aToProfile)
{
aInitTime = aTimer.ElapsedTime();
aTimer.Reset();
aTimer.Start();
}
// Perform shape self-intersection test
aTool.Perform();
if (!aTool.IsDone())
{
std::cout << "Error: Failed to perform proximity test" << std::endl;
return 1;
}
if (aToProfile)
{
aWorkTime = aTimer.ElapsedTime();
aTimer.Stop();
theDI << "Building data structure (BVH): " << aInitTime << "\n";
theDI << "Executing self-intersection test: " << aWorkTime << "\n";
}
// Extract output faces
TopoDS_Builder aCompBuilder;
TopoDS_Compound aFaceCompound;
aCompBuilder.MakeCompound (aFaceCompound);
for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt (aTool.OverlapElements()); anIt.More(); anIt.Next())
{
TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[1]) + "_" + (anIt.Key() + 1);
const TopoDS_Face& aFace = aTool.GetSubShape (anIt.Key());
aCompBuilder.Add (aFaceCompound, aFace);
DBRep::Set (aStr.ToCString(), aFace);
theDI << aStr << " \n";
}
theDI << "Compound of overlapped sub-faces: " << theArgs[1] << "_overlapped\n";
DBRep::Set ((TCollection_AsciiString (theArgs[1]) + "_" + "overlapped").ToCString(), aFaceCompound);
return 0;
}
//=======================================================================
//function : ExtremaCommands
//purpose :
@@ -432,17 +313,4 @@ void BRepTest::ExtremaCommands (Draw_Interpretor& theCommands)
__FILE__,
ShapeProximity,
aGroup);
theCommands.Add ("selfintersect",
"selfintersect Shape [-tol <value>] [-profile]"
"\n\t\t: Searches for intersected/overlapped faces in the given shape."
"\n\t\t: The algorithm uses shape tessellation (should be computed in"
"\n\t\t: advance), and provides approximate results. The options are:"
"\n\t\t: -tol : non-negative tolerance value used for overlapping"
"\n\t\t: test (for zero tolerance, the strict intersection"
"\n\t\t: test will be performed)"
"\n\t\t: -profile : outputs execution time for main algorithm stages",
__FILE__,
ShapeSelfIntersection,
aGroup);
}

View File

@@ -41,22 +41,14 @@ Standard_IMPORT Draw_Viewer dout;
Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
if (n < 2) {
di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z] [-full]" << "\n";
di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z]" << "\n";
di << "Compute properties of the shape" << "\n";
di << "The epsilon, if given, defines relative precision of computation" << "\n";
di << "The \"closed\" flag, if present, do computation only closed shells of the shape" << "\n";
di << "The centroid coordinates will be put to DRAW variables x y z (if given)\n";
di << "All values are outputted with the full precision in the full mode.\n\n";
di << "The centroid coordinates will be put to DRAW variables x y z (if given)\n" << "\n";
return 1;
}
Standard_Boolean isFullMode = Standard_False;
if (n >= 2 && strcmp(a[n-1], "-full") == 0)
{
isFullMode = Standard_True;
--n;
}
TopoDS_Shape S = DBRep::Get(a[1]);
if (S.IsNull()) return 0;
@@ -95,70 +87,45 @@ Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
Draw::Set(a[shift+3],P.Y());
Draw::Set(a[shift+4],P.Z());
}
Standard_SStream aSStream1;
aSStream1 << "\n\n";
aSStream1 << "Mass : " << setw(15) << G.Mass() << "\n" << "\n";
if(witheps && *a[0] != 'l') aSStream1 << "Relative error of mass computation : " << setw(15) << eps << "\n" << "\n";
aSStream1 << "Center of gravity : \n";
aSStream1 << "X = " << setw(15) << P.X() << "\n";
aSStream1 << "Y = " << setw(15) << P.Y() << "\n";
aSStream1 << "Z = " << setw(15) << P.Z() << "\n";
aSStream1 << "\n";
aSStream1 << "Matrix of Inertia : \n";
aSStream1 << setw(15) << I(1,1);
aSStream1 << " " << setw(15) << I(1,2);
aSStream1 << " " << setw(15) << I(1,3) << "\n";
aSStream1 << setw(15) << I(2,1);
aSStream1 << " " << setw(15) << I(2,2);
aSStream1 << " " << setw(15) << I(2,3) << "\n";
aSStream1 << setw(15) << I(3,1);
aSStream1 << " " << setw(15) << I(3,2);
aSStream1 << " " << setw(15) << I(3,3) << "\n";
aSStream1 << "\n";
aSStream1 << ends;
di << aSStream1;
GProp_PrincipalProps Pr = G.PrincipalProperties();
Standard_Real Ix,Iy,Iz;
Pr.Moments(Ix,Iy,Iz);
if (!isFullMode)
{
Standard_SStream aSStream1;
aSStream1 << "\n\n";
aSStream1 << "Mass : " << setw(15) << G.Mass() << "\n" << "\n";
if(witheps && *a[0] != 'l') aSStream1 << "Relative error of mass computation : " << setw(15) << eps << "\n" << "\n";
aSStream1 << "Center of gravity : \n";
aSStream1 << "X = " << setw(15) << P.X() << "\n";
aSStream1 << "Y = " << setw(15) << P.Y() << "\n";
aSStream1 << "Z = " << setw(15) << P.Z() << "\n";
aSStream1 << "\n";
aSStream1 << "Matrix of Inertia : \n";
aSStream1 << setw(15) << I(1,1);
aSStream1 << " " << setw(15) << I(1,2);
aSStream1 << " " << setw(15) << I(1,3) << "\n";
aSStream1 << setw(15) << I(2,1);
aSStream1 << " " << setw(15) << I(2,2);
aSStream1 << " " << setw(15) << I(2,3) << "\n";
aSStream1 << setw(15) << I(3,1);
aSStream1 << " " << setw(15) << I(3,2);
aSStream1 << " " << setw(15) << I(3,3) << "\n";
aSStream1 << "\n";
aSStream1 << ends;
di << aSStream1;
Standard_SStream aSStream2;
aSStream2 << "Moments : \n";
aSStream2 << "IX = " << setw(15) << Ix << "\n";
aSStream2 << "IY = " << setw(15) << Iy << "\n";
aSStream2 << "IZ = " << setw(15) << Iz << "\n";
aSStream2 << "\n";
aSStream2 << ends;
di << aSStream2;
}
else
{
di << "\n\nMass : " << G.Mass() << "\n\n";
if (witheps && *a[0] != 'l')
{
di << "Relative error of mass computation : " << eps << "\n\n";
}
di << "Center of gravity : \n";
di << "X = " << P.X() << "\n";
di << "Y = " << P.Y() << "\n";
di << "Z = " << P.Z() << "\n\n";
di << "Matrix of Inertia :\n";
di << I(1,1) << " " << I(1,2) << " " << I(1,3) << "\n";
di << I(2,1) << " " << I(2,2) << " " << I(2,3) << "\n";
di << I(3,1) << " " << I(3,2) << " " << I(3,3) << "\n\n";
di << "Moments :\n";
di << "IX = " << Ix << "\n";
di << "IY = " << Iy << "\n";
di << "IZ = " << Iz << "\n\n";
}
Standard_SStream aSStream2;
aSStream2 << "Moments : \n";
aSStream2 << "IX = " << setw(15) << Ix << "\n";
aSStream2 << "IY = " << setw(15) << Iy << "\n";
aSStream2 << "IZ = " << setw(15) << Iz << "\n";
aSStream2 << "\n";
aSStream2 << ends;
di << aSStream2;
//if (n == 2) {
gp_Ax2 axes(P,Pr.ThirdAxisOfInertia(),Pr.FirstAxisOfInertia());
@@ -315,12 +282,20 @@ void BRepTest::GPropCommands(Draw_Interpretor& theCommands)
const char* g = "Global properties";
theCommands.Add("lprops",
"lprops name [x y z] [-full] : compute linear properties",
__FILE__, props, g);
theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-full] :\n"
" compute surfacic properties", __FILE__, props, g);
theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-full] :\n"
" compute volumic properties", __FILE__, props, g);
"lprops name [epsilon] [x y z] : compute linear properties",
__FILE__,
props,
g);
theCommands.Add("sprops",
"sprops name [epsilon] [x y z] : compute surfacic properties",
__FILE__,
props,
g);
theCommands.Add("vprops",
"vprops name [epsilon] [c[losed]] [x y z] : compute volumic properties",
__FILE__,
props,
g);
theCommands.Add("vpropsgk",
"vpropsgk name epsilon closed span mode [x y z] : compute volumic properties",

View File

@@ -104,8 +104,6 @@ uses TColStd, gp, TColgp, math, GeomAbs
is
imported transient class Cache;
imported EvaluatorFunction ;
@@ -2065,30 +2063,6 @@ is
-- If rational computes the homogeneous Taylor expension
-- for the numerator and stores it in CachePoles
BuildCache(theParameter : Real;
theSpanDomain : Real;
thePeriodicFlag : Boolean ;
theDegree : Integer;
theFlatKnots : Array1OfReal from TColStd ;
thePoles : Array1OfPnt from TColgp;
theWeights : Array1OfReal from TColStd ;
theCacheArray : in out Array2OfReal from TColStd) ;
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplCLib_Cache.
BuildCache(theParameter : Real;
theSpanDomain : Real;
thePeriodicFlag : Boolean ;
theDegree : Integer;
theFlatKnots : Array1OfReal from TColStd ;
thePoles : Array1OfPnt2d from TColgp;
theWeights : Array1OfReal from TColStd ;
theCacheArray : in out Array2OfReal from TColStd) ;
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplCLib_Cache.
PolesCoefficients(Poles : Array1OfPnt2d from TColgp;
CachePoles : in out Array1OfPnt2d from TColgp);
---Warning: To be used for Beziercurves ONLY!!!
@@ -2480,7 +2454,6 @@ is
-- all u1 and u0 in the domain of the curve f(u)
-- | u1 - u0 | < UTolerance and
-- we have |f (u1) - f (u0)| < Tolerance3D
end BSplCLib;

View File

@@ -73,7 +73,6 @@ void BSplCLib::Hunt (const Array1OfReal& XX,
{
// replaced by simple dichotomy (RLE)
Ilc = XX.Lower();
if (XX.Length() <= 1) return;
const Standard_Real *px = &XX(Ilc);
px -= Ilc;
@@ -275,10 +274,6 @@ void BSplCLib::LocateParameter
while (val <= Eps) {
KnotIndex++;
if(KnotIndex >= Knots.Upper())
break;
K1 = K2;
K2 = knots[KnotIndex + 1];
val = K2 - K1;

View File

@@ -1,362 +0,0 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BSplCLib_Cache.hxx>
#include <BSplCLib.hxx>
#include <NCollection_LocalArray.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
IMPLEMENT_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BSplCLib_Cache, Standard_Transient)
//! Converts handle of array of Standard_Real into the pointer to Standard_Real
static Standard_Real* ConvertArray(const Handle_TColStd_HArray2OfReal& theHArray)
{
const TColStd_Array2OfReal& anArray = theHArray->Array2();
return (Standard_Real*) &(anArray(anArray.LowerRow(), anArray.LowerCol()));
}
BSplCLib_Cache::BSplCLib_Cache()
{
myPolesWeights.Nullify();
myIsRational = Standard_False;
mySpanStart = 0.0;
mySpanLength = 0.0;
mySpanIndex = 0;
myDegree = 0;
myFlatKnots.Nullify();
}
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights)
{
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
BuildCache(aCacheParam, theDegree, thePeriodic,
theFlatKnots, thePoles2d, theWeights);
}
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights)
{
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
BuildCache(aCacheParam, theDegree, thePeriodic,
theFlatKnots, thePoles, theWeights);
}
Standard_Boolean BSplCLib_Cache::IsCacheValid(Standard_Real theParameter) const
{
Standard_Real aNewParam = theParameter;
if (!myFlatKnots.IsNull())
PeriodicNormalization(myFlatKnots->Array1(), aNewParam);
Standard_Real aDelta = aNewParam - mySpanStart;
return (aDelta >= 0.0 && (aDelta < mySpanLength || mySpanIndex == mySpanIndexMax));
}
void BSplCLib_Cache::PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const
{
Standard_Real aPeriod = theFlatKnots.Value(theFlatKnots.Upper() - myDegree) -
theFlatKnots.Value(myDegree + 1) ;
if (theParameter < theFlatKnots.Value(myDegree + 1))
{
Standard_Real aScale = IntegerPart(
(theFlatKnots.Value(myDegree + 1) - theParameter) / aPeriod);
theParameter += aPeriod * (aScale + 1.0);
}
if (theParameter > theFlatKnots.Value(theFlatKnots.Upper() - myDegree))
{
Standard_Real aScale = IntegerPart(
(theParameter - theFlatKnots.Value(theFlatKnots.Upper() - myDegree)) / aPeriod);
theParameter -= aPeriod * (aScale + 1.0);
}
}
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights)
{
// Normalize theParameter for periodical B-splines
Standard_Real aNewParam = theParameter;
if (thePeriodic)
{
PeriodicNormalization(theFlatKnots, aNewParam);
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
myFlatKnots->ChangeArray1() = theFlatKnots;
}
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
myFlatKnots.Nullify();
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 3 : 2;
if (theDegree > myDegree)
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
myDegree = theDegree;
mySpanIndex = 0;
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
aNewParam, thePeriodic, mySpanIndex, aNewParam);
mySpanStart = theFlatKnots.Value(mySpanIndex);
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
// Calculate new cache data
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
theFlatKnots, thePoles2d, theWeights,
myPolesWeights->ChangeArray2());
}
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights)
{
// Create list of knots with repetitions and normalize theParameter for periodical B-splines
Standard_Real aNewParam = theParameter;
if (thePeriodic)
{
PeriodicNormalization(theFlatKnots, aNewParam);
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
myFlatKnots->ChangeArray1() = theFlatKnots;
}
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
myFlatKnots.Nullify();
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 4 : 3;
if (theDegree > myDegree)
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
myDegree = theDegree;
mySpanIndex = 0;
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
aNewParam, thePeriodic, mySpanIndex, aNewParam);
mySpanStart = theFlatKnots.Value(mySpanIndex);
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
// Calculate new cache data
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
theFlatKnots, thePoles, theWeights,
myPolesWeights->ChangeArray2());
}
void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
// Temporary container. The maximal size of this container is defined by:
// 1) maximal derivative for cache evaluation, which is 3, plus one row for function values,
// 2) and maximal dimension of the point, which is 3, plus one column for weights.
Standard_Real aTmpContainer[16];
// When the PLib::RationaDerivative needs to be called, use temporary container
Standard_Real* aPntDeriv = myIsRational ? aTmpContainer : &theDerivArray;
// When the degree of curve is lesser than the requested derivative,
// nullify array cells corresponding to greater derivatives
Standard_Integer aDerivative = theDerivative;
if (myDegree < theDerivative)
{
aDerivative = myDegree;
for (Standard_Integer ind = myDegree * aDimension; ind < (theDerivative + 1) * aDimension; ind++)
{
aPntDeriv[ind] = 0.0;
(&theDerivArray)[ind] = 0.0; // should be cleared separately, because aPntDeriv may look to another memory area
}
}
PLib::EvalPolynomial(aNewParameter, aDerivative, myDegree, aDimension,
aPolesArray[0], aPntDeriv[0]);
// Unnormalize derivatives since those are computed normalized
Standard_Real aFactor = 1.0;
for (Standard_Integer deriv = 1; deriv <= aDerivative; deriv++)
{
aFactor /= mySpanLength;
for (Standard_Integer ind = 0; ind < aDimension; ind++)
aPntDeriv[aDimension * deriv + ind] *= aFactor;
}
if (myIsRational) // calculate derivatives divided by weights derivatives
PLib::RationalDerivative(aDerivative, aDerivative, aDimension - 1, aPntDeriv[0], theDerivArray);
}
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
aDimension, myDegree * aDimension,
aPolesArray[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[2]);
}
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
aDimension, myDegree * aDimension,
aPolesArray[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[3]);
}
void BSplCLib_Cache::D1(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
}
void BSplCLib_Cache::D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
}
void BSplCLib_Cache::D2(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent, gp_Vec2d& theCurvature) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
theCurvature.SetCoord(aPntDeriv[aDimension<<1], aPntDeriv[(aDimension<<1) + 1]);
}
void BSplCLib_Cache::D2(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent, gp_Vec& theCurvature) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
theCurvature.SetCoord(aPntDeriv[aDimension<<1], aPntDeriv[(aDimension<<1) + 1], aPntDeriv[(aDimension<<1) + 2]);
}
void BSplCLib_Cache::D3(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature,
gp_Vec2d& theTorsion) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
Standard_Integer aShift = aDimension << 1;
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
aShift += aDimension;
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
}
void BSplCLib_Cache::D3(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
Standard_Integer aShift = aDimension << 1;
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
aShift += aDimension;
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
}

View File

@@ -1,182 +0,0 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BSplCLib_Cache_Headerfile
#define _BSplCLib_Cache_Headerfile
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Transient.hxx>
#include <Handle_TColStd_HArray1OfReal.hxx>
#include <Handle_TColStd_HArray2OfReal.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Vec.hxx>
class Handle(BSplCLib_Cache);
class TColStd_Array1OfReal;
class TColgp_Array1OfPnt;
class TColgp_Array1OfPnt2d;
#ifndef NOWEIGHTS_CURVE
#define NOWEIGHTS_CURVE (*((TColStd_Array1OfReal*) NULL))
#endif
//! \brief A cache class for B-spline curves.
//!
//! Defines all data, that can be cached on a span of B-spline curve.
//! The data should be recalculated in going from span to span.
class BSplCLib_Cache : public Standard_Transient
{
public:
//! Default constructor
Standard_EXPORT BSplCLib_Cache();
//! Constructor for caching of 2D curves
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles2d array of poles of 2D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Constructor for caching of 3D curves
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles array of poles of 3D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Verifies validity of the cache using flat parameter of the point
//! \param theParameter parameter of the point placed in the span
Standard_EXPORT Standard_Boolean IsCacheValid(Standard_Real theParameter) const;
//! Recomputes the cache data for 2D curves. Does not verify validity of the cache
//! \param theParameter the value on the knot's axis to identify the span
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles2d array of poles of 2D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Recomputes the cache data for 3D curves. Does not verify validity of the cache
//! \param theParameter the value on the knot's axis to identify the span
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles array of poles of 3D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Calculates the point on B-spline in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const;
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const;
//! Calculates the point on B-spline and its first derivative in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (first derivatives) for B-spline in the calculated point
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const;
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const;
//! Calculates the point on B-spline and two derivatives in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
Standard_EXPORT void D2(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature) const;
Standard_EXPORT void D2(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature) const;
//! Calculates the point on B-spline and three derivatives in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
//! \param[out] theTorsion second curvature vector (3rd derivatives) for B-spline in the calculated point
Standard_EXPORT void D3(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature,
gp_Vec2d& theTorsion) const;
Standard_EXPORT void D3(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const;
DEFINE_STANDARD_RTTI(BSplCLib_Cache)
protected:
//! Normalizes the parameter for periodical B-splines
//! \param theFlatKnots knots with repetitions
//! \param theParameter the value to be normalized into the knots array
void PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots, Standard_Real& theParameter) const;
//! Fills array of derivatives in the selected point of the B-spline
//! \param[in] theParameter parameter of the calculation
//! \param[in] theDerivative maximal derivative to be calculated (computes all derivatives lesser than specified)
//! \param[out] theDerivArray result array of derivatives (with size (theDerivative+1)*(PntDim+1),
//! where PntDim = 2 or 3 is a dimension of B-spline curve)
void CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const;
private:
Handle(TColStd_HArray2OfReal) myPolesWeights; ///< array of poles and weights of calculated cache
// the array has following structure:
// x1 y1 [z1] [w1]
// x2 y2 [z2] [w2] etc
// for 2D-curves there is no z conponent, for non-rational curves there is no weight
Standard_Boolean myIsRational; ///< identifies the rationality of B-spline
Standard_Real mySpanStart; ///< parameter for the first point of the span
Standard_Real mySpanLength; ///< length of the span
Standard_Integer mySpanIndex; ///< index of the span on B-spline curve
Standard_Integer mySpanIndexMax; ///< maximal number of spans on B-spline curve
Standard_Integer myDegree; ///< degree of B-spline
Handle(TColStd_HArray1OfReal) myFlatKnots; ///< knots of B-spline (used for periodic normalization of parameters, exists only for periodical splines)
};
DEFINE_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
#endif

View File

@@ -19,7 +19,6 @@
// xab : 12-Mar-96 : added MovePointAndTangent
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <gp_Vec2d.hxx>
#include <Standard_ConstructionError.hxx>
#include <PLib.hxx>
@@ -1090,65 +1089,6 @@ void BSplCLib::BuildCache
}
}
void BSplCLib::BuildCache(const Standard_Real theParameter,
const Standard_Real theSpanDomain,
const Standard_Boolean thePeriodicFlag,
const Standard_Integer theDegree,
const TColStd_Array1OfReal& theFlatKnots,
const Array1OfPoints& thePoles,
const TColStd_Array1OfReal& theWeights,
TColStd_Array2OfReal& theCacheArray)
{
Standard_Real aParam = theParameter;
Standard_Integer anIndex = 0;
Standard_Integer aDimension;
Standard_Boolean isRational;
BSplCLib_DataContainer dc(theDegree);
PrepareEval(aParam,
anIndex,
aDimension,
isRational,
theDegree,
thePeriodicFlag,
thePoles,
theWeights,
theFlatKnots,
(BSplCLib::NoMults()),
dc);
//
// Watch out : PrepareEval checks if locally the Bspline is polynomial
// therefore rational flag could be set to False even if there are
// Weights. The Dimension is set accordingly.
//
Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the curve is locally polynomial
(&theWeights != NULL && !isRational) ? aDimension + 1 : aDimension;
BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles);
Standard_Real aCoeff = 1.0;
Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
Standard_Real* aPolyCoeffs = dc.poles;
for (Standard_Integer i = 0; i <= theDegree; i++)
{
for (Standard_Integer j = 0; j< aDimension; j++)
aCache[j] = aPolyCoeffs[j] * aCoeff;
aCoeff *= theSpanDomain / (i+1);
aPolyCoeffs += aDimension;
aCache += aDimension;
if (aCacheShift > aDimension)
{
aCache[0] = 0.0;
aCache++;
}
}
if (aCacheShift > aDimension)
theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
}
//=======================================================================
//function : Interpolate
//purpose :

View File

@@ -4,5 +4,4 @@ BSplCLib_3.cxx
BSplCLib_BzSyntaxes.cxx
BSplCLib_CurveComputation.gxx
BSplCLib_EvaluatorFunction.hxx
BSplCLib_Cache.hxx
BSplCLib_Cache.cxx

View File

@@ -71,8 +71,6 @@ uses TColStd, gp, TColgp
is
imported transient class Cache;
imported EvaluatorFunction ;
---Purpose:
@@ -467,19 +465,6 @@ is
--
--
BuildCache(theU, theV : Real;
theUSpanDomain, theVSpanDomain : Real;
theUPeriodic, theVPeriodic : Boolean;
theUDegree, theVDegree : Integer;
theUIndex, theVIndex : Integer;
theUFlatKnots, theVFlatKnots : Array1OfReal from TColStd;
thePoles : Array2OfPnt from TColgp;
theWeights : Array2OfReal from TColStd;
theCacheArray : in out Array2OfReal from TColStd);
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplSLib_Cache.
CacheD0(U,V : Real;
UDegree,VDegree : Integer;
UCacheParameter,VCacheParameter : Real;

View File

@@ -570,9 +570,6 @@ static Standard_Boolean PrepareEval (const Standard_Real U,
if(ip < PLowerRow)
ip = PUpperRow;
if(ip > PUpperRow)
ip = PLowerRow;
for (j = 0; j <= d2; j++)
{
const gp_Pnt& P = Poles.Value(ip,jp);
@@ -2046,101 +2043,6 @@ void BSplSLib::BuildCache
}
}
void BSplSLib::BuildCache(const Standard_Real theU,
const Standard_Real theV,
const Standard_Real theUSpanDomain,
const Standard_Real theVSpanDomain,
const Standard_Boolean theUPeriodicFlag,
const Standard_Boolean theVPeriodicFlag,
const Standard_Integer theUDegree,
const Standard_Integer theVDegree,
const Standard_Integer theUIndex,
const Standard_Integer theVIndex,
const TColStd_Array1OfReal& theUFlatKnots,
const TColStd_Array1OfReal& theVFlatKnots,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights,
TColStd_Array2OfReal& theCacheArray)
{
Standard_Boolean flag_u_or_v;
Standard_Integer d1, d2;
Standard_Real u1, u2;
Standard_Boolean isRationalOnParam = (&theWeights != NULL);
Standard_Boolean isRational;
BSplSLib_DataContainer dc(theUDegree, theVDegree);
flag_u_or_v =
PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree,
isRationalOnParam, isRationalOnParam,
theUPeriodicFlag, theVPeriodicFlag,
thePoles, theWeights,
theUFlatKnots, theVFlatKnots,
(BSplCLib::NoMults()), (BSplCLib::NoMults()),
u1, u2, d1, d2, isRational, dc);
Standard_Integer d2p1 = d2 + 1;
Standard_Integer aDimension = isRational ? 4 : 3;
Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial
(isRationalOnParam && !isRational) ? aDimension + 1 : aDimension;
Standard_Real aDomains[2];
// aDomains[0] corresponds to variable with minimal degree
// aDomains[1] corresponds to variable with maximal degree
if (flag_u_or_v)
{
aDomains[0] = theUSpanDomain;
aDomains[1] = theVSpanDomain;
}
else
{
aDomains[0] = theVSpanDomain;
aDomains[1] = theUSpanDomain;
}
BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles);
for (Standard_Integer kk = 0; kk <= d1 ; kk++)
BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1));
Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
Standard_Real* aPolyCoeffs = dc.poles;
Standard_Real aFactors[2];
// aFactors[0] corresponds to variable with minimal degree
// aFactors[1] corresponds to variable with maximal degree
aFactors[1] = 1.0;
Standard_Integer aRow, aCol, i;
Standard_Real aCoeff;
for (aRow = 0; aRow <= d2; aRow++)
{
aFactors[0] = 1.0;
for (aCol = 0; aCol <= d1; aCol++)
{
aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension;
aCoeff = aFactors[0] * aFactors[1];
for (i = 0; i < aDimension; i++)
aCache[i] = aPolyCoeffs[i] * aCoeff;
aCache += aCacheShift;
aFactors[0] *= aDomains[0] / (aCol + 1);
}
aFactors[1] *= aDomains[1] / (aRow + 1);
}
// Fill the weights for the surface which is not locally polynomial
if (aCacheShift > aDimension)
{
aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
aCache += aCacheShift - 1;
for (aRow = 0; aRow <= d2; aRow++)
for (aCol = 0; aCol <= d1; aCol++)
{
*aCache = 0.0;
aCache += aCacheShift;
}
theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
}
}
//=======================================================================
//function : CacheD0
//purpose : Evaluates the polynomial cache of the Bspline Curve

View File

@@ -1,419 +0,0 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BSplSLib_Cache.hxx>
#include <BSplSLib.hxx>
#include <NCollection_LocalArray.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
IMPLEMENT_STANDARD_HANDLE(BSplSLib_Cache, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BSplSLib_Cache, Standard_Transient)
//! Converts handle of array of Standard_Real into the pointer to Standard_Real
static Standard_Real* ConvertArray(const Handle_TColStd_HArray2OfReal& theHArray)
{
const TColStd_Array2OfReal& anArray = theHArray->Array2();
return (Standard_Real*) &(anArray(anArray.LowerRow(), anArray.LowerCol()));
}
BSplSLib_Cache::BSplSLib_Cache()
{
myPolesWeights.Nullify();
myIsRational = Standard_False;
mySpanStart[0] = mySpanStart[1] = 0.0;
mySpanLength[0] = mySpanLength[1] = 0.0;
mySpanIndex[0] = mySpanIndex[1] = 0;
myDegree[0] = myDegree[1] = 0;
myFlatKnots[0].Nullify();
myFlatKnots[1].Nullify();
}
BSplSLib_Cache::BSplSLib_Cache(const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights)
{
Standard_Real aU = theFlatKnotsU.Value(theFlatKnotsU.Lower() + theDegreeU);
Standard_Real aV = theFlatKnotsV.Value(theFlatKnotsV.Lower() + theDegreeV);
BuildCache(aU, aV,
theDegreeU, thePeriodicU, theFlatKnotsU,
theDegreeV, thePeriodicV, theFlatKnotsV,
thePoles, theWeights);
}
Standard_Boolean BSplSLib_Cache::IsCacheValid(Standard_Real theParameterU,
Standard_Real theParameterV) const
{
Standard_Real aNewU = theParameterU;
Standard_Real aNewV = theParameterV;
if (!myFlatKnots[0].IsNull())
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
if (!myFlatKnots[1].IsNull())
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
Standard_Real aDelta0 = aNewU - mySpanStart[0];
Standard_Real aDelta1 = aNewV - mySpanStart[1];
return (aDelta0 >= -mySpanLength[0] && (aDelta0 < mySpanLength[0] || mySpanIndex[0] == mySpanIndexMax[0]) &&
aDelta1 >= -mySpanLength[1] && (aDelta1 < mySpanLength[1] || mySpanIndex[1] == mySpanIndexMax[1]));
}
void BSplSLib_Cache::PeriodicNormalization(const Standard_Integer& theDegree,
const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const
{
Standard_Real aPeriod = theFlatKnots.Value(theFlatKnots.Upper() - theDegree) -
theFlatKnots.Value(theDegree + 1) ;
if (theParameter < theFlatKnots.Value(theDegree + 1))
{
Standard_Real aScale = IntegerPart(
(theFlatKnots.Value(theDegree + 1) - theParameter) / aPeriod);
theParameter += aPeriod * (aScale + 1.0);
}
if (theParameter > theFlatKnots.Value(theFlatKnots.Upper() - theDegree))
{
Standard_Real aScale = IntegerPart(
(theParameter - theFlatKnots.Value(theFlatKnots.Upper() - theDegree)) / aPeriod);
theParameter -= aPeriod * (aScale + 1.0);
}
}
void BSplSLib_Cache::BuildCache(const Standard_Real& theParameterU,
const Standard_Real& theParameterV,
const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights)
{
// Normalize the parameters for periodical B-splines
Standard_Real aNewParamU = theParameterU;
if (thePeriodicU)
{
PeriodicNormalization(theDegreeU, theFlatKnotsU, aNewParamU);
myFlatKnots[0] = new TColStd_HArray1OfReal(1, theFlatKnotsU.Length());
myFlatKnots[0]->ChangeArray1() = theFlatKnotsU;
}
else if (!myFlatKnots[0].IsNull()) // Periodical curve became non-periodical
myFlatKnots[0].Nullify();
Standard_Real aNewParamV = theParameterV;
if (thePeriodicV)
{
PeriodicNormalization(theDegreeV, theFlatKnotsV, aNewParamV);
myFlatKnots[1] = new TColStd_HArray1OfReal(1, theFlatKnotsV.Length());
myFlatKnots[1]->ChangeArray1() = theFlatKnotsV;
}
else if (!myFlatKnots[1].IsNull()) // Periodical curve became non-periodical
myFlatKnots[1].Nullify();
Standard_Integer aMinDegree = Min(theDegreeU, theDegreeV);
Standard_Integer aMaxDegree = Max(theDegreeU, theDegreeV);
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 4 : 3;
if (theDegreeU > myDegree[0] || theDegreeV > myDegree[1])
myPolesWeights = new TColStd_HArray2OfReal(1, aMaxDegree + 1, 1, aPWColNumber * (aMinDegree + 1));
myDegree[0] = theDegreeU;
myDegree[1] = theDegreeV;
mySpanIndex[0] = mySpanIndex[1] = 0;
BSplCLib::LocateParameter(theDegreeU, theFlatKnotsU, BSplCLib::NoMults(), aNewParamU,
thePeriodicU, mySpanIndex[0], aNewParamU);
BSplCLib::LocateParameter(theDegreeV, theFlatKnotsV, BSplCLib::NoMults(), aNewParamV,
thePeriodicV, mySpanIndex[1], aNewParamV);
// Protection against Out of Range exception.
if (mySpanIndex[0] >= theFlatKnotsU.Length()) {
mySpanIndex[0] = theFlatKnotsU.Length() - 1;
}
mySpanLength[0] = (theFlatKnotsU.Value(mySpanIndex[0] + 1) - theFlatKnotsU.Value(mySpanIndex[0])) * 0.5;
mySpanStart[0] = theFlatKnotsU.Value(mySpanIndex[0]) + mySpanLength[0];
// Protection against Out of Range exception.
if (mySpanIndex[1] >= theFlatKnotsV.Length()) {
mySpanIndex[1] = theFlatKnotsV.Length() - 1;
}
mySpanLength[1] = (theFlatKnotsV.Value(mySpanIndex[1] + 1) - theFlatKnotsV.Value(mySpanIndex[1])) * 0.5;
mySpanStart[1] = theFlatKnotsV.Value(mySpanIndex[1]) + mySpanLength[1];
mySpanIndexMax[0] = theFlatKnotsU.Length() - 1 - theDegreeU;
mySpanIndexMax[1] = theFlatKnotsV.Length() - 1 - theDegreeV;
// Calculate new cache data
BSplSLib::BuildCache(mySpanStart[0], mySpanStart[1],
mySpanLength[0], mySpanLength[1],
thePeriodicU, thePeriodicV,
theDegreeU, theDegreeV,
mySpanIndex[0], mySpanIndex[1],
theFlatKnotsU, theFlatKnotsV,
thePoles, theWeights, myPolesWeights->ChangeArray2());
}
void BSplSLib_Cache::D0(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) / mySpanLength[0];
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) / mySpanLength[1];
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(aCacheCols); // array for intermediate results
// Calculate intermediate value of cached polynomial along columns
PLib::NoDerivativeEvalPolynomial(aParameters[1], aMinMaxDegree[1],
aCacheCols, aMinMaxDegree[1] * aCacheCols,
aPolesArray[0], aTransientCoeffs[0]);
// Calculate total value
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0],
aDimension, aDimension * aMinMaxDegree[0],
aTransientCoeffs[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[3]);
}
void BSplSLib_Cache::D1(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
Standard_Real anInvU = 1.0 / mySpanLength[0];
Standard_Real anInvV = 1.0 / mySpanLength[1];
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) * anInvU;
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) * anInvV;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPntDeriv[16]; // result storage (point and derivative coordinates)
for (Standard_Integer i = 0; i< 16; i++) aPntDeriv[i] = 0.0;
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(aCacheCols<<1); // array for intermediate results
// Calculate intermediate values and derivatives of bivariate polynomial along variable with maximal degree
PLib::EvalPolynomial(aParameters[1], 1, aMinMaxDegree[1], aCacheCols, aPolesArray[0], aTransientCoeffs[0]);
// Calculate a point on surface and a derivative along variable with minimal degree
PLib::EvalPolynomial(aParameters[0], 1, aMinMaxDegree[0], aDimension, aTransientCoeffs[0], aPntDeriv[0]);
// Calculate derivative along variable with maximal degree
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0], aDimension,
aMinMaxDegree[0] * aDimension, aTransientCoeffs[aCacheCols],
aPntDeriv[aDimension<<1]);
Standard_Real* aResult = aPntDeriv;
Standard_Real aTempStorage[12];
if (myIsRational) // calculate derivatives divided by weight's derivatives
{
BSplSLib::RationalDerivative(1, 1, 1, 1, aPntDeriv[0], aTempStorage[0]);
aResult = aTempStorage;
aDimension--;
}
thePoint.SetCoord(aResult[0], aResult[1], aResult[2]);
if (myDegree[0] > myDegree[1])
{
theTangentV.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theTangentU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
else
{
theTangentU.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theTangentV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
theTangentU.Multiply(anInvU);
theTangentV.Multiply(anInvV);
}
void BSplSLib_Cache::D2(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV,
gp_Vec& theCurvatureU,
gp_Vec& theCurvatureV,
gp_Vec& theCurvatureUV) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
Standard_Real anInvU = 1.0 / mySpanLength[0];
Standard_Real anInvV = 1.0 / mySpanLength[1];
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) * anInvU;
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) * anInvV;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPntDeriv[36]; // result storage (point and derivative coordinates)
for (Standard_Integer i = 0; i < 36; i++) aPntDeriv[i] = 0.0;
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(3 * aCacheCols); // array for intermediate results
// Calculating derivative to be evaluate and
// nulling transient coefficients when max or min derivative is less than 2
Standard_Integer aMinMaxDeriv[2] = {Min(2, aMinMaxDegree[0]),
Min(2, aMinMaxDegree[1])};
for (Standard_Integer i = aMinMaxDeriv[1] + 1; i < 3; i++)
{
Standard_Integer index = i * aCacheCols;
for (Standard_Integer j = 0; j < aCacheCols; j++)
aTransientCoeffs[index++] = 0.0;
}
// Calculate intermediate values and derivatives of bivariate polynomial along variable with maximal degree
PLib::EvalPolynomial(aParameters[1], aMinMaxDeriv[1], aMinMaxDegree[1],
aCacheCols, aPolesArray[0], aTransientCoeffs[0]);
// Calculate a point on surface and a derivatives along variable with minimal degree
PLib::EvalPolynomial(aParameters[0], aMinMaxDeriv[0], aMinMaxDegree[0],
aDimension, aTransientCoeffs[0], aPntDeriv[0]);
// Calculate derivative along variable with maximal degree and mixed derivative
PLib::EvalPolynomial(aParameters[0], 1, aMinMaxDegree[0], aDimension,
aTransientCoeffs[aCacheCols], aPntDeriv[3 * aDimension]);
// Calculate second derivative along variable with maximal degree
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0], aDimension,
aMinMaxDegree[0] * aDimension, aTransientCoeffs[aCacheCols<<1],
aPntDeriv[6 * aDimension]);
Standard_Real* aResult = aPntDeriv;
Standard_Real aTempStorage[36];
if (myIsRational) // calculate derivatives divided by weight's derivatives
{
BSplSLib::RationalDerivative(2, 2, 2, 2, aPntDeriv[0], aTempStorage[0]);
aResult = aTempStorage;
aDimension--;
}
thePoint.SetCoord(aResult[0], aResult[1], aResult[2]);
if (myDegree[0] > myDegree[1])
{
theTangentV.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theCurvatureV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theTangentU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theCurvatureUV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += (aDimension << 1);
theCurvatureU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
else
{
theTangentU.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theCurvatureU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theTangentV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theCurvatureUV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += (aDimension << 1);
theCurvatureV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
theTangentU.Multiply(anInvU);
theTangentV.Multiply(anInvV);
theCurvatureU.Multiply(anInvU * anInvU);
theCurvatureV.Multiply(anInvV * anInvV);
theCurvatureUV.Multiply(anInvU * anInvV);
}

View File

@@ -1,161 +0,0 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BSplSLib_Cache_Headerfile
#define _BSplSLib_Cache_Headerfile
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Transient.hxx>
#include <Handle_TColStd_HArray1OfReal.hxx>
#include <Handle_TColStd_HArray2OfReal.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
class Handle(BSplSLib_Cache);
class TColgp_Array2OfPnt;
class TColStd_Array1OfInteger;
class TColStd_Array1OfReal;
class TColStd_Array2OfReal;
#ifndef NOWEIGHTS_SURF
#define NOWEIGHTS_SURF (*((TColStd_Array2OfReal*) NULL))
#endif
//! \brief A cache class for B-spline surfaces.
//!
//! Defines all data, that can be cached on a span of B-spline surface.
//! The data should be recalculated in going from span to span.
class BSplSLib_Cache : public Standard_Transient
{
public:
//! Default constructor
Standard_EXPORT BSplSLib_Cache();
//! Constructor for caching of the span for B-spline surface
//! \param theDegreeU degree along the first parameter (U) of the B-spline
//! \param thePeriodicU identify the B-spline is periodical along U axis
//! \param theFlatKnotsU knots of B-spline curve (with repetition) along U axis
//! \param theDegreeV degree alogn the second parameter (V) of the B-spline
//! \param thePeriodicV identify the B-spline is periodical along V axis
//! \param theFlatKnotsV knots of B-spline curve (with repetition) along V axis
//! \param thePoles array of poles of the B-spline surface
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplSLib_Cache(const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights = NOWEIGHTS_SURF);
//! Verifies validity of the cache using parameters of the point
//! \param theParameterU first parameter of the point placed in the span
//! \param theParameterV second parameter of the point placed in the span
Standard_EXPORT Standard_Boolean IsCacheValid(Standard_Real theParameterU,
Standard_Real theParameterV) const;
//! Recomputes the cache data. Does not verify validity of the cache
//! \param theParameterU the parametric value on the U axis to identify the span
//! \param theParameterV the parametric value on the V axis to identify the span
//! \param theDegreeU degree of the B-spline along U axis
//! \param thePeriodicU identify the B-spline is periodic along U axis
//! \param theFlatKnotsU flat knots of B-spline surface along U axis
//! \param theDegreeV degree of the B-spline along V axis
//! \param thePeriodicV identify the B-spline is periodic along V axis
//! \param theFlatKnotsV flat knots of B-spline surface along V axis
//! \param thePoles array of poles of B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameterU,
const Standard_Real& theParameterV,
const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights = NOWEIGHTS_SURF);
//! Calculates the point on B-spline for specified parameters
//! \param[in] theU first parameter for calculation of the value
//! \param[in] theV second parameter for calculation of the value
//! \param[out] thePoint the result of calculation (the point on the B-spline)
Standard_EXPORT void D0(const Standard_Real& theU, const Standard_Real& theV, gp_Pnt& thePoint) const;
//! Calculates the point on B-spline and its first derivative
//! \param[in] theU first parameter of calculation of the value
//! \param[in] theV second parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on the B-spline)
//! \param[out] theTangentU tangent vector along U axis in the calculated point
//! \param[out] theTangentV tangent vector along V axis in the calculated point
Standard_EXPORT void D1(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV) const;
//! Calculates the point on B-spline and derivatives till second order
//! \param[in] theU first parameter of calculation of the value
//! \param[in] theV second parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangentU tangent vector along U axis in the calculated point
//! \param[out] theTangentV tangent vector along V axis in the calculated point
//! \param[out] theCurvatureU curvature vector (2nd derivative on U) along U axis
//! \param[out] theCurvatureV curvature vector (2nd derivative on V) along V axis
//! \param[out] theCurvatureUV 2nd mixed derivative on U anv V
Standard_EXPORT void D2(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV,
gp_Vec& theCurvatureU,
gp_Vec& theCurvatureV,
gp_Vec& theCurvatureUV) const;
DEFINE_STANDARD_RTTI(BSplSLib_Cache)
protected:
//! Normalizes the parameter for periodical B-splines
//! \param[in] theDegree degree of B-spline along selected direction
//! \param[in] theFlatKnots knots with repetitions along selected direction
//! \param[in,out] theParameter the value to be normalized into the knots array
void PeriodicNormalization(const Standard_Integer& theDegree,
const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const;
private:
Handle(TColStd_HArray2OfReal) myPolesWeights; ///< array of poles and weights of calculated cache
// the array has following structure:
// x11 y11 z11 [w11] x12 y12 z12 [w12] ...
// x21 y21 z21 [w21] x22 y22 z22 [w22] etc
// for non-rational surfaces there is no weight;
// size of array: (max(myDegree)+1) * A*(min(myDegree)+1), where A = 4 or 3
Standard_Boolean myIsRational; ///< identifies the rationality of B-spline
Standard_Real mySpanStart[2]; ///< parameters (u, v) for the frst point of the span
Standard_Real mySpanLength[2]; ///< lengths of the span along corresponding parameter
Standard_Integer mySpanIndex[2]; ///< indexes of the span on B-spline surface
Standard_Integer mySpanIndexMax[2]; ///< maximal indexes of span
Standard_Integer myDegree[2]; ///< degrees of B-spline for each parameter
Handle(TColStd_HArray1OfReal) myFlatKnots[2]; ///< arrays of knots of B-spline
// (used for periodic normalization of parameters, Null for non-periodical splines)
};
DEFINE_STANDARD_HANDLE(BSplSLib_Cache, Standard_Transient)
#endif

View File

@@ -1,4 +1,3 @@
BSplSLib_BzSyntaxes.cxx
BSplSLib_EvaluatorFunction.hxx
BSplSLib_Cache.hxx
BSplSLib_Cache.cxx

View File

@@ -45,22 +45,20 @@ uses
Point from Geom2d ,
Pnt2d from gp ,
Vec2d from gp ,
Integer from Standard,
JoinType from GeomAbs
Integer from Standard
is
Create returns Bisec from Bisector;
Perform(me : in out ;
Cu1 : Curve from Geom2d ;
Cu2 : Curve from Geom2d ;
P : Pnt2d from gp ;
V1 : Vec2d from gp ;
V2 : Vec2d from gp ;
Sense : Real from Standard ;
ajointype : JoinType from GeomAbs ;
Tolerance : Real from Standard ;
oncurve : Boolean from Standard = Standard_True );
Cu1 : Curve from Geom2d ;
Cu2 : Curve from Geom2d ;
P : Pnt2d from gp ;
V1 : Vec2d from gp ;
V2 : Vec2d from gp ;
Sense : Real from Standard ;
Tolerance : Real from Standard ;
oncurve : Boolean from Standard = Standard_True );
--- Purpose : Performs the bisecting line between the curves
-- <Cu1> and <Cu2>.

View File

@@ -73,14 +73,13 @@ Bisector_Bisec::Bisector_Bisec()
//===========================================================================
void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
const Handle(Geom2d_Curve)& asecondcurve ,
const gp_Pnt2d& apoint ,
const gp_Vec2d& afirstvector ,
const gp_Vec2d& asecondvector ,
const Standard_Real adirection ,
const GeomAbs_JoinType ajointype ,
const Standard_Real tolerance ,
const Standard_Boolean oncurve )
const Handle(Geom2d_Curve)& asecondcurve ,
const gp_Pnt2d& apoint ,
const gp_Vec2d& afirstvector ,
const gp_Vec2d& asecondvector ,
const Standard_Real adirection ,
const Standard_Real tolerance ,
const Standard_Boolean oncurve )
{
Handle(Standard_Type) Type1 = afirstcurve ->DynamicType();
Handle(Standard_Type) Type2 = asecondcurve->DynamicType();
@@ -150,19 +149,18 @@ void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
//------------------------------------------------------------------
// Analytic Bissectrice.
//------------------------------------------------------------------
Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
BisAna->Perform(afirstcurve1 ,
asecondcurve1 ,
apoint ,
afirstvector ,
asecondvector ,
adirection ,
ajointype ,
tolerance ,
oncurve );
UFirst = BisAna->ParameterOfStartPoint();
ULast = BisAna->ParameterOfEndPoint();
Bis = BisAna;
Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
BisAna->Perform(afirstcurve1 ,
asecondcurve1 ,
apoint ,
afirstvector ,
asecondvector ,
adirection ,
tolerance ,
oncurve );
UFirst = BisAna->ParameterOfStartPoint();
ULast = BisAna->ParameterOfEndPoint();
Bis = BisAna;
}
else {
Standard_Boolean IsLine = Standard_False;

View File

@@ -27,7 +27,6 @@ inherits
uses
Shape from GeomAbs,
CurveType from GeomAbs,
JoinType from GeomAbs,
Curve from Geom2d,
Geometry from Geom2d,
TrimmedCurve from Geom2d,
@@ -44,15 +43,14 @@ is
Create returns BisecAna;
Perform(me : mutable ;
Cu1 : Curve from Geom2d ;
Cu2 : Curve from Geom2d ;
P : Pnt2d from gp ;
V1 : Vec2d from gp ;
V2 : Vec2d from gp ;
Sense : Real from Standard ;
jointype : JoinType from GeomAbs ;
Tolerance : Real from Standard ;
oncurve : Boolean from Standard = Standard_True );
Cu1 : Curve from Geom2d ;
Cu2 : Curve from Geom2d ;
P : Pnt2d from gp ;
V1 : Vec2d from gp ;
V2 : Vec2d from gp ;
Sense : Real from Standard ;
Tolerance : Real from Standard ;
oncurve : Boolean from Standard = Standard_True );
--- Purpose : Performs the bisecting line between the curves
-- <Cu1> and <Cu2>.
@@ -127,8 +125,7 @@ is
Sense : Real from Standard ;
U : out Real from Standard ;
sense : out Boolean from Standard ;
ok : out Boolean from Standard ;
IsBisecOfTwoLines : Boolean from Standard = Standard_False)
ok : out Boolean from Standard )
--- Purpose : Returns the distance between the point <P> and
-- the bisecting <Bis>.

View File

@@ -76,8 +76,7 @@ Standard_Real Bisector_BisecAna::Distance (
const Standard_Real adirection,
Standard_Real& aparameter,
Standard_Boolean& asense,
Standard_Boolean& astatus,
Standard_Boolean IsBisecOfTwoLines)
Standard_Boolean& astatus)
{
astatus = Standard_True;
@@ -154,36 +153,30 @@ Standard_Real Bisector_BisecAna::Distance (
else {
asense = Standard_True;
if (!IsBisecOfTwoLines)
{
// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 Begin
// Replacement of -1.E-8 for a tolerance 1.e-4
Standard_Real aTol = 1.e-4;
if ((afirstdir^secdirrev)*adirection < -0.1) { // input
if((afirstdir^tangdir)*adirection < aTol &&
(secdirrev^tangdir)*adirection < aTol)
asense = Standard_False;
}
else if((afirstdir^secdirrev)*adirection > 0.1) { // output
if((afirstdir^tangdir)*adirection < aTol ||
(secdirrev^tangdir)*adirection < aTol)
asense = Standard_False;
}
else { // flat
if (afirstdir.Dot(secdirrev) > 0.) { // tangent
if ((afirstdir^tangdir)*adirection < 0.)
asense = Standard_False;
}
else{ // turn back
// Modified by Sergey KHROMOV - Thu Oct 31 14:16:53 2002
// if ((afirstdir.Dot(tangdir))*adirection > 0.) asense = Standard_False;
if (afirstdir.Dot(tangdir) < 0.) asense = Standard_False;
// Modified by Sergey KHROMOV - Thu Oct 31 14:16:54 2002
}
}
// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 End
// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 Begin
// Replacement of -1.E-8 for a tolerance 1.e-4
Standard_Real aTol = 1.e-4;
if ((afirstdir^secdirrev)*adirection < -0.1) { // input
if((afirstdir^tangdir)*adirection < aTol &&
(secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
}
else if((afirstdir^secdirrev)*adirection > 0.1) { // output
if((afirstdir^tangdir)*adirection < aTol ||
(secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
}
else { // flat
if (afirstdir.Dot(secdirrev) > 0.) { // tangent
if ((afirstdir^tangdir)*adirection < 0.) asense = Standard_False;
}
else{ // turn back
// Modified by Sergey KHROMOV - Thu Oct 31 14:16:53 2002
// if ((afirstdir.Dot(tangdir))*adirection > 0.) asense = Standard_False;
if (afirstdir.Dot(tangdir) < 0.) asense = Standard_False;
// Modified by Sergey KHROMOV - Thu Oct 31 14:16:54 2002
}
}
// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 End
}
return distance;
}
@@ -205,7 +198,6 @@ void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
const gp_Vec2d& afirstvector ,
const gp_Vec2d& asecondvector ,
const Standard_Real adirection ,
const GeomAbs_JoinType ajointype ,
const Standard_Real tolerance ,
const Standard_Boolean oncurve )
{
@@ -633,26 +625,14 @@ void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
}
else if (type == GccInt_Par) {
bisectorcurve = new Geom2d_Parabola(TheSol->Parabola());
Standard_Real FocalLength = ((Handle(Geom2d_Parabola)&)bisectorcurve)->Focal();
Standard_Real secondparameter = Precision::Infinite();
if (!thesense)
{
if (ajointype == GeomAbs_Intersection &&
4.*FocalLength < firstparameter) //first parameter is too far from peak of parabola
secondparameter = 0.;
thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
firstparameter,
-secondparameter);
}
- Precision::Infinite());
else
{
if (ajointype == GeomAbs_Intersection &&
firstparameter < -4.*FocalLength) //first parameter is too far from peak of parabola
secondparameter = 0.;
thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
firstparameter,
secondparameter);
}
Precision::Infinite());
}
}
}
@@ -734,7 +714,7 @@ void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
else
distanceptsol = Distance(apoint,solution,
afirstvector,asecondvector,
adirection,parameter,sense,ok, Standard_True);
adirection,parameter,sense,ok);
// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
if (ok || !oncurve) {
thesense = sense;

View File

@@ -19,6 +19,8 @@
#include <TColStd_Array1OfReal.hxx>
#include <math_Vector.hxx>
#include <math_Matrix.hxx>
//#include <math_StackMemoryManager.hxx>
//#include <math_Memory.hxx>
BlendFunc_Tensor::BlendFunc_Tensor(const Standard_Integer NbRow,
const Standard_Integer NbCol,

View File

@@ -165,13 +165,7 @@ gp_Dir& Normal
// if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag;
}
else
{
// Firstly normalize tangent vectors D1U and D1V (this method is more stable)
gp_Dir aD1U(D1U);
gp_Dir aD1V(D1V);
Normal = gp_Dir(aD1U.Crossed(aD1V));
Status = Defined;
}
{ Normal = gp_Dir (D1UvD1V); Status = Defined; }
}

View File

@@ -1,470 +0,0 @@
// Copyright (c) 2015-... OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <CSLib_Offset.hxx>
#include <gp_Dir2d.hxx>
#include <gp_XY.hxx>
#include <Geom_UndefinedValue.hxx>
#include <Geom_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Standard_NullValue.hxx>
// ========== Offset values for 2D curves ==========
void CSLib_Offset::D0(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseDeriv,
Standard_Real theOffset,
Standard_Boolean , // unused
gp_Pnt2d& theResPoint)
{
if (theBaseDeriv.SquareMagnitude() <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Undefined normal vector "
"because tangent vector has zero-magnitude!");
gp_Dir2d aNormal(theBaseDeriv.Y(), -theBaseDeriv.X());
theResPoint.SetCoord(theBasePoint.X() + aNormal.X() * theOffset,
theBasePoint.Y() + aNormal.Y() * theOffset);
}
void CSLib_Offset::D1(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
Standard_Real theOffset,
Standard_Boolean , // unused
gp_Pnt2d& theResPoint,
gp_Vec2d& theResDeriv)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot(DNdir);
if (R3 <= gp::Resolution())
{
if (R2 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good.
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffset / R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better
DNdir.Multiply(theOffset / R);
DNdir.Subtract(Ndir.Multiplied(theOffset * Dr / R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffset, Standard_False, theResPoint);
// P'(u)
theResDeriv = theBaseD1.Added(gp_Vec2d(DNdir));
}
void CSLib_Offset::D2(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
gp_XY D2Ndir(theBaseD3.Y(), -theBaseD3.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt(R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot(DNdir);
Standard_Real D2r = Ndir.Dot(D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution())
{
if (R4 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good dixit ISG.
// V2 = P" (U) :
D2Ndir.Subtract(DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add(Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply(theOffset / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffset / R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better.
// V2 = P" (U) :
D2Ndir.Multiply(theOffset / R);
D2Ndir.Subtract(DNdir.Multiplied (2.0 * theOffset * Dr / R3));
D2Ndir.Add (Ndir.Multiplied(theOffset * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U)
DNdir.Multiply(theOffset / R);
DNdir.Subtract(Ndir.Multiplied(theOffset * Dr / R3));
}
// P(u) :
D0(theBasePoint, theBaseD1, theOffset, theIsDirectionChange, theResPoint);
// P'(u) :
theResD1 = theBaseD1.Added(gp_Vec2d(DNdir));
// P"(u) :
if (theIsDirectionChange)
theResD2 = -theBaseD2;
else
theResD2 = theBaseD2;
theResD2.Add(gp_Vec2d(D2Ndir));
}
void CSLib_Offset::D3(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
const gp_Vec2d& theBaseD4,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2,
gp_Vec2d& theResD3)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
// P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
// (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
gp_XY D2Ndir(theBaseD3.Y(), -theBaseD3.X());
gp_XY D3Ndir(theBaseD4.Y(), -theBaseD4.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real R6 = R3 * R3;
Standard_Real R7 = R5 * R2;
Standard_Real Dr = Ndir.Dot(DNdir);
Standard_Real D2r = Ndir.Dot(D2Ndir) + DNdir.Dot (DNdir);
Standard_Real D3r = Ndir.Dot(D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
if (R7 <= gp::Resolution())
{
if (R6 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good dixit ISG.
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * theOffset * Dr / R2));
D3Ndir.Subtract (
(DNdir.Multiplied ((3.0 * theOffset) * ((D2r/R2) + (Dr*Dr)/R4))));
D3Ndir.Add (Ndir.Multiplied (
(theOffset * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r))));
D3Ndir.Multiply (theOffset/R);
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (theOffset / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffset/R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better.
// V3 = P"' (U) :
D3Ndir.Multiply (theOffset/R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * theOffset * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied (
((3.0 * theOffset) * ((D2r/R3) + (Dr*Dr)/R5))) );
D3Ndir.Add (Ndir.Multiplied (
(theOffset * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))));
// V2 = P" (U) :
D2Ndir.Multiply (theOffset/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * theOffset * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied (
theOffset * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U) :
DNdir.Multiply (theOffset/R);
DNdir.Subtract (Ndir.Multiplied (theOffset*Dr/R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffset, theIsDirectionChange, theResPoint);
// P'(u)
theResD1 = theBaseD1.Added(gp_Vec2d(DNdir));
// P"(u)
theResD2 = theBaseD2.Added(gp_Vec2d(D2Ndir));
// P"'(u)
if (theIsDirectionChange)
theResD3 = -theBaseD3;
else
theResD3 = theBaseD3;
theResD3.Add(gp_Vec2d(D2Ndir));
}
// ========== Offset values for 3D curves ==========
void CSLib_Offset::D0(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseDeriv,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean , // unused
gp_Pnt& theResPoint)
{
gp_XYZ Ndir = (theBaseDeriv.XYZ()).Crossed(theOffsetDirection.XYZ());
Standard_Real R = Ndir.Modulus();
if (R <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Ndir.Multiply(theOffsetValue / R);
Ndir.Add(theBasePoint.XYZ());
theResPoint.SetXYZ(Ndir);
}
void CSLib_Offset::D1(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean , // unused
gp_Pnt& theResPoint,
gp_Vec& theResDeriv)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
if (R3 <= gp::Resolution()) {
if (R2 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good.
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffsetValue / R2);
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply(theOffsetValue / R);
DNdir.Subtract(Ndir.Multiplied(theOffsetValue * Dr / R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, Standard_False, theResPoint);
// P'(u)
theResDeriv = theBaseD1.Added(gp_Vec(DNdir));
}
void CSLib_Offset::D2(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D2Ndir = (theBaseD3.XYZ()).Crossed(theOffsetDirection.XYZ());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution()) {
if (R4 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good
//dixit ISG.
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (theOffsetValue / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffsetValue/R2);
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (theOffsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * theOffsetValue * Dr / R3));
D2Ndir.Add (Ndir.Multiplied (theOffsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U) :
DNdir.Multiply (theOffsetValue/R);
DNdir.Subtract (Ndir.Multiplied (theOffsetValue*Dr/R3));
}
// P(u) :
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, theIsDirectionChange, theResPoint);
// P'(u) :
theResD1 = theBaseD1.Added(gp_Vec(DNdir));
// P"(u) :
if (theIsDirectionChange)
theResD2 = -theBaseD2;
else
theResD2 = theBaseD2;
theResD2.Add(gp_Vec(D2Ndir));
}
void CSLib_Offset::D3(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Vec& theBaseD4,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2,
gp_Vec& theResD3)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
//P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2) * D2Ndir -
// (3.0 * D2r / R2) * DNdir + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D2Ndir = (theBaseD3.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D3Ndir = (theBaseD4.XYZ()).Crossed(theOffsetDirection.XYZ());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real R6 = R3 * R3;
Standard_Real R7 = R5 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
if (R7 <= gp::Resolution()) {
if (R6 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2));
D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r));
D3Ndir.Multiply (theOffsetValue/R);
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2)));
D2Ndir.Multiply (theOffsetValue / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffsetValue/R2);
}
else {
// V3 = P"' (U) :
D3Ndir.Divide (R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r));
D3Ndir.Multiply (theOffsetValue);
// V2 = P" (U) :
D2Ndir.Divide (R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3)));
D2Ndir.Multiply (theOffsetValue);
// V1 = P' (U) :
DNdir.Multiply (theOffsetValue/R);
DNdir.Subtract (Ndir.Multiplied (theOffsetValue*Dr/R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, theIsDirectionChange, theResPoint);
// P'(u)
theResD1 = theBaseD1.Added(gp_Vec(DNdir));
// P"(u)
theResD2 = theBaseD2.Added(gp_Vec(D2Ndir));
// P"'(u)
if (theIsDirectionChange)
theResD3 = -theBaseD3;
else
theResD3 = theBaseD3;
theResD3.Add(gp_Vec(D2Ndir));
}

View File

@@ -1,190 +0,0 @@
// Copyright (c) 2015-... OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _CSLib_Offset_Headerfile
#define _CSLib_Offset_Headerfile
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Standard.hxx>
/** \namespace CSLib_Offset
* \brief Provides a number of static methods to calculate values and derivatives
* of an offset curves and surfaces using values and derivatives of
* a base curve/surface.
*/
namespace CSLib_Offset
{
/** \brief Calculate value of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseDeriv derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
*/
Standard_EXPORT void D0(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseDeriv,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint);
/** \brief Calculate value of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseDeriv derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
*/
Standard_EXPORT void D0(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseDeriv,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint);
/** \brief Calculate value and the first derivative of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
* \param[out] theResDeriv derivative on offset curve
*/
Standard_EXPORT void D1(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResDeriv);
/** \brief Calculate value and the first derivative of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
* \param[out] theResDeriv derivative on offset curve
*/
Standard_EXPORT void D1(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResDeriv);
/** \brief Calculate value and two derivatives of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
*/
Standard_EXPORT void D2(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2);
/** \brief Calculate value and two derivatives of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
*/
Standard_EXPORT void D2(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2);
/** \brief Calculate value and three derivatives of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theBaseD4 fourth derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
* \param[out] theResD3 third derivative on offset curve
*/
Standard_EXPORT void D3(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
const gp_Vec2d& theBaseD4,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2,
gp_Vec2d& theResD3);
/** \brief Calculate value and three derivatives of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theBaseD4 fourth derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
* \param[out] theResD3 third derivative on offset curve
*/
Standard_EXPORT void D3(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Vec& theBaseD4,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2,
gp_Vec& theResD3);
}
#endif // _CSLib_Offset_Headerfile

View File

@@ -1,2 +0,0 @@
CSLib_Offset.hxx
CSLib_Offset.cxx

View File

@@ -199,7 +199,7 @@ static Standard_Integer CommandCmd
if (cc && Draw::Atoi(cc)) {
#ifdef WNT
Tcl_Finalize();
Tcl_Exit(0);
#else
Tcl_Eval(interp,"exit");
#endif
@@ -558,7 +558,7 @@ Draw_Interpretor::~Draw_Interpretor()
#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
try {
OCC_CATCH_SIGNALS
Tcl_Finalize();
Tcl_Exit(0);
}
catch (Standard_Failure) {
#ifdef OCCT_DEBUG
@@ -567,7 +567,7 @@ Draw_Interpretor::~Draw_Interpretor()
}
#else
#ifdef WNT
Tcl_Finalize();
Tcl_Exit(0);
#endif
#endif
}

View File

@@ -1206,7 +1206,7 @@ static void StdinProc(ClientData clientData, int )
if (count < 0) {
if (!gotPartial) {
if (tty) {
Tcl_Finalize();
Tcl_Exit(0);
} else {
Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
}
@@ -2103,7 +2103,7 @@ static DWORD WINAPI tkLoop(VOID)
fprintf (stderr, "%s\n", interp->result);
#endif
cout << "tkLoop: Tk_MainWindow() returned NULL. Exiting...\n";
Tcl_Finalize();
Tcl_Exit (0);
}
Tk_Name(mainWindow) = Tk_GetUid (Tk_SetAppName (mainWindow, "Draw"));
}
@@ -2147,7 +2147,7 @@ static DWORD WINAPI tkLoop(VOID)
toLoop = (Tk_GetNumMainWindows() > 0) || Draw_VirtualWindows;
#endif
}
Tcl_Finalize();
Tcl_Exit(0);
return 0;
}

View File

@@ -236,10 +236,10 @@ proc vsamples {} {
set istitlefound 0
while {[gets $chan line] >= 0} {
if {[lindex [split $line " "] 0] == "#Category:"} {
set acategory [string trim [string trimleft $line "#Category: "]]
set acategory [string trimleft $line "#Category: "]
}
if {[lindex [split $line " "] 0] == "#Title:"} {
set atitle [string trim [string trimleft $line "#Title: "]]
set atitle [string trimleft $line "#Title: "]
lappend alistofthree $acategory $atitle $fname
incr istitlefound
break

View File

@@ -591,9 +591,6 @@ help testdiff {
1 - output only differences
2 - output also list of logs and directories present in one of dirs only
3 - (default) output also progress messages
-highlight_percent value: highlight considerable (>value in %) deviations
of CPU and memory (default value is 5%)
}
proc testdiff {dir1 dir2 args} {
if { "$dir1" == "$dir2" } {
@@ -609,7 +606,6 @@ proc testdiff {dir1 dir2 args} {
set basename ""
set status "same"
set verbose 3
set highlight_percent 5
for {set narg 0} {$narg < [llength $args]} {incr narg} {
set arg [lindex $args $narg]
@@ -646,18 +642,7 @@ proc testdiff {dir1 dir2 args} {
}
continue
}
# highlight_percent
if { $arg == "-highlight_percent" } {
incr narg
if { $narg < [llength $args] && ! [regexp {^-} [lindex $args $narg]] } {
set highlight_percent [expr [lindex $args $narg]]
} else {
error "Error: Option -highlight_percent must be followed by integer value"
}
continue
}
if { [regexp {^-} $arg] } {
error "Error: unsupported option \"$arg\""
}
@@ -672,7 +657,7 @@ proc testdiff {dir1 dir2 args} {
# save result to log file
if { "$logfile" != "" } {
_log_save $logfile [join $log "\n"]
_log_html_diff "[file rootname $logfile].html" $log $dir1 $dir2 ${highlight_percent}
_log_html_diff "[file rootname $logfile].html" $log $dir1 $dir2
puts "Log is saved to $logfile (and .html)"
}
@@ -1893,7 +1878,7 @@ proc _test_diff {dir1 dir2 basename status verbose _logvar {_statvar ""}} {
}
# Auxiliary procedure to save log of results comparison to file
proc _log_html_diff {file log dir1 dir2 highlight_percent} {
proc _log_html_diff {file log dir1 dir2} {
# create missing directories as needed
catch {file mkdir [file dirname $file]}
@@ -1913,9 +1898,9 @@ proc _log_html_diff {file log dir1 dir2 highlight_percent} {
puts $fd "<pre>"
set logpath [file split [file normalize $file]]
foreach line $log {
# put a line; highlight considerable (> ${highlight_percent}%) deviations of CPU and memory
# put a line; highlight considerable (>5%) deviations of CPU and memory
if { [regexp "\[\\\[](\[0-9.e+-]+)%\[\]]" $line res value] &&
[expr abs($value)] > ${highlight_percent} } {
[expr abs($value)] > 5 } {
puts $fd "<table><tr><td bgcolor=\"[expr $value > 0 ? \"red\" : \"lightgreen\"]\">$line</td></tr></table>"
} else {
puts $fd $line

View File

@@ -678,44 +678,50 @@ void Extrema_ExtCC::Results(const Extrema_ECC& AlgExt,
const Standard_Real Ut21,
const Standard_Real Ut22)
{
Standard_Integer i, NbExt;
Standard_Real Val, U, U2;
Extrema_POnCurv P1, P2;
Standard_Integer i, j,NbExt;
Standard_Real Val, U, U2,Uj,U2j;
Extrema_POnCurv P1, P2,P1j,P2j;
Standard_Boolean IsExtrema;
myDone = AlgExt.IsDone();
if (myDone)
{
myIsPar = AlgExt.IsParallel();
if (myDone) {
NbExt = AlgExt.NbExt();
for (i = 1; i <= NbExt; i++)
{
for (i = 1; i <= NbExt; i++) {
AlgExt.Points(i, P1, P2);
U = P1.Parameter();
U2 = P2.Parameter();
IsExtrema=Standard_True;
for (j=1;j<=mynbext;j++)
{ P1j=mypoints.Value(2*j-1);
P2j=mypoints.Value(2*j);
Uj=P1j.Parameter();
U2j=P2j.Parameter();
if ((Abs(Uj-U)<=myTol[0]) && (Abs(U2j-U2)<=myTol[1]))
IsExtrema=Standard_False;}
if (IsExtrema)
{
// Verification de la validite des parametres
if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[0]))) {
U = ElCLib::InPeriod(U, Ut11, Ut11+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[0])));
}
if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[1]))) {
U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[1])));
}
// Check points to be into param space.
if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[0])))
{
U = ElCLib::InPeriod(U, Ut11, Ut11+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[0])));
}
if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[1])))
{
U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[1])));
}
if ((U >= Ut11 - RealEpsilon()) &&
(U <= Ut12 + RealEpsilon()) &&
(U2 >= Ut21 - RealEpsilon()) &&
(U2 <= Ut22 + RealEpsilon()) )
{
mynbext++;
Val = AlgExt.SquareDistance(i);
mySqDist.Append(Val);
P1.SetValues(U, P1.Value());
P2.SetValues(U2, P2.Value());
mypoints.Append(P1);
mypoints.Append(P2);
if ((U >= Ut11 - RealEpsilon()) &&
(U <= Ut12 + RealEpsilon()) &&
(U2 >= Ut21 - RealEpsilon()) &&
(U2 <= Ut22 + RealEpsilon()))
{ mynbext++;
Val = AlgExt.SquareDistance(i);
mySqDist.Append(Val);
P1.SetValues(U, P1.Value());
P2.SetValues(U2, P2.Value());
mypoints.Append(P1);
mypoints.Append(P2);
}
}
}
}
}
}

View File

@@ -512,7 +512,6 @@ void Extrema_ExtCC2d::Results(const Extrema_ECC2d& AlgExt,
myDone = AlgExt.IsDone();
if (myDone)
{
myIsPar = AlgExt.IsParallel();
if (!myIsPar)
{
NbExt = AlgExt.NbExt();

View File

@@ -410,7 +410,7 @@ Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
Standard_Integer Extrema_ExtCS::NbExt() const
{
if(!myDone) StdFail_NotDone::Raise();
return myPOnC.Length();
return mySqDist.Length();
}

View File

@@ -146,34 +146,6 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
IntExtIsDone = IntExtIsDone || mydone;
}
mydone = IntExtIsDone;
// Additional checking if the point is on the first or last point of the curve and does not added yet
if (mydist1 < Precision::SquareConfusion() || mydist2 < Precision::SquareConfusion())
{
Standard_Boolean isFirstAdded = Standard_False;
Standard_Boolean isLastAdded = Standard_False;
Standard_Integer aNbPoints = mypoint.Length();
for (i = 1; i <= aNbPoints; i++)
{
U = mypoint.Value(i).Parameter();
if (Abs(U - myuinf) < mytolu)
isFirstAdded = Standard_True;
else if (Abs(myusup - U) < mytolu)
isLastAdded = Standard_True;
}
if (!isFirstAdded && mydist1 < Precision::SquareConfusion())
{
mySqDist.Prepend(mydist1);
myismin.Prepend(Standard_True);
mypoint.Prepend(ThePOnC(myuinf, Pf));
}
if (!isLastAdded && mydist2 < Precision::SquareConfusion())
{
mySqDist.Append(mydist2);
myismin.Append(Standard_True);
mypoint.Append(ThePOnC(myusup, Pl));
}
}
return;
}
}

View File

@@ -66,10 +66,6 @@ is
---Purpose: Returns True if the distances are found.
is static;
IsParallel (me) returns Boolean
---Purpose: Returns state of myParallel flag.
is static;
NbExt (me) returns Integer
---Purpose: Returns the number of extremum distances.
raises NotDone from StdFail,
@@ -100,7 +96,6 @@ is
is static;
fields
myParallel : Boolean;
myCurveMinTol : Real from Standard;
myLowBorder : Vector from math;
myUppBorder : Vector from math;

View File

@@ -14,8 +14,6 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <algorithm>
#include <Extrema_GlobOptFuncCC.hxx>
#include <math_GlobOptMin.hxx>
#include <Standard_NullObject.hxx>
@@ -23,82 +21,13 @@
#include <StdFail_NotDone.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Precision.hxx>
#include <NCollection_Vector.hxx>
#include <NCollection_CellFilter.hxx>
// Comparator, used in std::sort.
static Standard_Boolean comp(const gp_XY& theA,
const gp_XY& theB)
{
if (theA.X() < theB.X())
{
return Standard_True;
}
else
{
if (theA.X() == theB.X())
{
if (theA.Y() <= theB.Y())
return Standard_True;
}
}
return Standard_False;
}
class Extrema_CCPointsInspector : public NCollection_CellFilter_InspectorXY
{
public:
typedef gp_XY Target;
//! Constructor; remembers the tolerance
Extrema_CCPointsInspector (const Standard_Real theTol)
{
myTol = theTol * theTol;
myIsFind = Standard_False;
}
void ClearFind()
{
myIsFind = Standard_False;
}
Standard_Boolean isFind()
{
return myIsFind;
}
//! Set current point to search for coincidence
void SetCurrent (const gp_XY& theCurPnt)
{
myCurrent = theCurPnt;
}
//! Implementation of inspection method
NCollection_CellFilter_Action Inspect (const Target& theObject)
{
gp_XY aPt = myCurrent.Subtracted(theObject);
const Standard_Real aSQDist = aPt.SquareModulus();
if(aSQDist < myTol)
{
myIsFind = Standard_True;
}
return CellFilter_Keep;
}
private:
Standard_Real myTol;
gp_XY myCurrent;
Standard_Boolean myIsFind;
};
//=======================================================================
//function : Extrema_GenExtCC
//purpose :
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC()
: myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
@@ -112,8 +41,7 @@ Extrema_GenExtCC::Extrema_GenExtCC()
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
const Curve2& C2)
: myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
@@ -136,8 +64,7 @@ Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
const Standard_Real Usup,
const Standard_Real Vinf,
const Standard_Real Vsup)
: myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
: myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
myDone(Standard_False)
@@ -185,7 +112,6 @@ void Extrema_GenExtCC::SetTolerance(Standard_Real theTol)
void Extrema_GenExtCC::Perform()
{
myDone = Standard_False;
myParallel = Standard_False;
Curve1 &C1 = *(Curve1*)myC[0];
Curve2 &C2 = *(Curve2*)myC[1];
@@ -205,19 +131,14 @@ void Extrema_GenExtCC::Perform()
Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
aFinder.SetTol(aDiscTol, aSameTol);
// Size computed to have cell index inside of int32 value.
const Standard_Real aCellSize = Max(anIntervals1.Upper() - anIntervals1.Lower(),
anIntervals2.Upper() - anIntervals2.Lower())
* Precision::PConfusion() / (2.0 * Sqrt(2.0));
Extrema_CCPointsInspector anInspector(Precision::PConfusion());
NCollection_CellFilter<Extrema_CCPointsInspector> aFilter(aCellSize);
NCollection_Vector<gp_XY> aPnts;
Standard_Real anEps1 = (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion();
Standard_Real anEps2 = (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion();
Standard_Integer i,j,k;
math_Vector aFirstBorderInterval(1,2);
math_Vector aSecondBorderInterval(1,2);
Standard_Real aF = RealLast(); // Best functional value.
Standard_Real aCurrF = RealLast(); // Current functional value computed on current interval.
Standard_Real aF = RealLast(); // best functional value
Standard_Real aCurrF = RealLast(); // current functional value computed on current interval
for(i = 1; i <= aNbInter[0]; i++)
{
for(j = 1; j <= aNbInter[1]; j++)
@@ -230,14 +151,14 @@ void Extrema_GenExtCC::Perform()
aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval);
aFinder.Perform();
// Check that solution found on current interval is not worse than previous.
// check that solution found on current interval is not worse than previous
aCurrF = aFinder.GetF();
if (aCurrF >= aF + aSameTol * aValueTol)
{
continue;
}
// Clean previously computed solution if current one is better.
// clean previously computed solution if current one is better
if (aCurrF > aF - aSameTol * aValueTol)
{
if (aCurrF < aF)
@@ -246,90 +167,33 @@ void Extrema_GenExtCC::Perform()
else
{
aF = aCurrF;
aFilter.Reset(aCellSize);
aPnts.Clear();
myPoints1.Clear();
myPoints2.Clear();
}
// Save found solutions avoiding repetitions.
// save found solutions avoiding repetitions
math_Vector sol(1,2);
for(k = 1; k <= aFinder.NbExtrema(); k++)
{
aFinder.Points(k, sol);
gp_XY aPnt2d(sol(1), sol(2));
gp_XY aXYmin = anInspector.Shift(aPnt2d, -aCellSize);
gp_XY aXYmax = anInspector.Shift(aPnt2d, aCellSize);
anInspector.ClearFind();
anInspector.SetCurrent(aPnt2d);
aFilter.Inspect(aXYmin, aXYmax, anInspector);
if (!anInspector.isFind())
// avoid duplicated points
Standard_Boolean isNew = Standard_True;
for (Standard_Integer iSol = 1; isNew && iSol <= myPoints1.Length(); iSol++)
{
// Point is out of close cells, add new one.
aFilter.Add(aPnt2d, aPnt2d);
aPnts.Append(gp_XY(sol(1), sol(2)));
if (Abs(myPoints1(iSol) - sol(1)) < anEps1 &&
Abs(myPoints2(iSol) - sol(2)) < anEps2)
isNew = Standard_False;
}
if (isNew)
{
myPoints1.Append(sol(1));
myPoints2.Append(sol(2));
}
}
}
}
if (aPnts.Size() == 0)
{
// No solutions.
myDone = Standard_False;
return;
}
// Check for infinity solutions case, for this:
// Sort points lexicographically and check midpoint between each two neighboring points.
// If all midpoints functional value is acceptable
// then set myParallel flag to true and return one soulution.
std::sort(aPnts.begin(), aPnts.end(), comp);
Standard_Boolean isParallel = Standard_False;
Standard_Real aVal = 0.0;
math_Vector aVec(1,2, 0.0);
// Avoid mark parallel case when have duplicates out of tolerance.
// Bad conditioned task: bug25635_1, bug23706_10, bug23706_13.
const Standard_Integer aMinNbInfSol = 100;
if (aPnts.Size() >= aMinNbInfSol)
{
isParallel = Standard_True;
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper() - 1; anIdx++)
{
const gp_XY& aCurrent = aPnts(anIdx);
const gp_XY& aNext = aPnts(anIdx + 1);
aVec(1) = (aCurrent.X() + aNext.X()) * 0.5;
aVec(2) = (aCurrent.Y() + aNext.Y()) * 0.5;
aFunc.Value(aVec, aVal);
if (Abs(aVal - aF) > Precision::Confusion())
{
isParallel = Standard_False;
break;
}
}
}
if (isParallel)
{
const gp_XY& aCurrent = aPnts.First();
myPoints1.Append(aCurrent.X());
myPoints2.Append(aCurrent.Y());
myParallel = Standard_True;
}
else
{
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper(); anIdx++)
{
const gp_XY& aCurrent = aPnts(anIdx);
myPoints1.Append(aCurrent.X());
myPoints2.Append(aCurrent.Y());
}
}
myDone = Standard_True;
}
@@ -342,15 +206,6 @@ Standard_Boolean Extrema_GenExtCC::IsDone() const
return myDone;
}
//=======================================================================
//function : IsParallel
//purpose :
//=======================================================================
Standard_Boolean Extrema_GenExtCC::IsParallel() const
{
return myParallel;
}
//=======================================================================
//function : NbExt
//purpose :
@@ -387,4 +242,4 @@ void Extrema_GenExtCC::Points(const Standard_Integer N,
P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)));
P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
}
}

View File

@@ -120,7 +120,8 @@ uses Array1OfInteger from TColStd,
Vec from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom,
Shape from GeomAbs
Shape from GeomAbs,
Mutex from Standard
raises ConstructionError from Standard,
@@ -589,6 +590,17 @@ is
---Purpose :
-- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real.
IsCacheValid(me; Parameter : Real) returns Boolean
---Purpose :
-- Tells whether the Cache is valid for the
-- given parameter
-- Warnings : the parameter must be normalized within
-- the period if the curve is periodic. Otherwise
-- the answer will be false
--
is static private;
Continuity (me) returns Shape from GeomAbs;
---Purpose :
@@ -777,15 +789,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of K is not equal to the number of knots.
Knots (me)
returns Array1OfReal from TColStd
---Purpose : returns the knot values of the B-spline curve;
-- Warning
-- A knot with a multiplicity greater than 1 is not
-- repeated in the knot table. The Multiplicity function
-- can be used to obtain the multiplicity of each knot.
---C++ : return const &
is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
@@ -842,12 +845,6 @@ is
-- Standard_DimensionError if the array K is not of
-- the appropriate length.Returns the knots sequence.
raises DimensionError;
KnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : returns the knots of the B-spline curve.
-- Knots with multiplicit greater than 1 are repeated
---C++ : return const &
is static;
@@ -913,11 +910,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of M is not equal to NbKnots.
Multiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : returns the multiplicity of the knots of the curve.
---C++ : return const &
is static;
NbKnots (me) returns Integer;
@@ -941,11 +933,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of P is not equal to the number of poles.
Poles (me)
returns Array1OfPnt from TColgp
---Purpose : Returns the poles of the B-spline curve;
---C++ : return const &
is static;
StartPoint (me) returns Pnt;
@@ -967,11 +954,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of W is not equal to NbPoles.
Weights (me)
returns Array1OfReal from TColStd
---Purpose : Returns the weights of the B-spline curve;
---C++ : return const &
is static;
@@ -999,10 +981,20 @@ is
Copy (me) returns like me;
---Purpose: Creates a new object which is a copy of this BSpline curve.
InvalidateCache(me : mutable)
---Purpose : Invalidates the cache. This has to be private
-- this has to be private
is static private;
UpdateKnots(me : mutable)
---Purpose : Recompute the flatknots, the knotsdistribution, the continuity.
is static private;
ValidateCache(me : mutable ; Parameter : Real)
is static private;
---Purpose : updates the cache and validates it
IsEqual(me; theOther : BSplineCurve from Geom;
thePreci : Real from Standard ) returns Boolean;
@@ -1023,7 +1015,34 @@ fields
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
cachepoles : HArray1OfPnt from TColgp;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
cacheweights : HArray1OfReal from TColStd;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
validcache : Integer;
-- = 1 the cache is valid
-- = 0 the cache is invalid
parametercache : Real;
-- Parameter at which the Taylor expension is stored in
-- the cache
spanlenghtcache : Real;
-- Since the Taylor expansion is normalized in the
-- cache to evaluate the cache one has to use
-- (Parameter - parametercache) / nspanlenghtcache
spanindexcache : Integer;
-- the span for which the cache is valid if
-- validcache is 1
-- usefull to evaluate the parametric resolution
maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bspline-cache
end;

View File

@@ -125,11 +125,12 @@ Geom_BSplineCurve::Geom_BSplineCurve
{
// check
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
// copy arrays
@@ -144,6 +145,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -168,11 +174,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
// check
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom_BSplineCurve");
@@ -191,9 +197,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
poles = new TColgp_HArray1OfPnt(1,Poles.Length());
poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
knots = new TColStd_HArray1OfReal(1,Knots.Length());
@@ -203,6 +211,9 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -587,7 +598,7 @@ void Geom_BSplineCurve::Segment(const Standard_Real U1,
BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
NewU2,periodic,FromU1,ToU2,index2,U);
if ( Abs(knots->Value(index2+1)-U) <= Eps || index2 == index1)
if ( Abs(knots->Value(index2+1)-U) <= Eps)
index2++;
Standard_Integer nbknots = index2 - index1 + 1;
@@ -963,6 +974,7 @@ void Geom_BSplineCurve::SetPole
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise();
poles->SetValue (Index, P);
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@@ -1011,6 +1023,7 @@ void Geom_BSplineCurve::SetWeight
rational = !weights.IsNull();
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@@ -1019,11 +1032,11 @@ void Geom_BSplineCurve::SetWeight
//=======================================================================
void Geom_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
const gp_Pnt& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
{
if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
@@ -1034,11 +1047,12 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0);
gp_Vec Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) {
poles->ChangeArray1() = npoles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1047,13 +1061,14 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
//purpose :
//=======================================================================
void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U,
const gp_Pnt& P,
const gp_Vec& Tangent,
const Standard_Real Tolerance,
const Standard_Integer StartingCondition,
const Standard_Integer EndingCondition,
Standard_Integer& ErrorStatus)
void Geom_BSplineCurve::
MovePointAndTangent(const Standard_Real U,
const gp_Pnt& P,
const gp_Vec& Tangent,
const Standard_Real Tolerance,
const Standard_Integer StartingCondition,
const Standard_Integer EndingCondition,
Standard_Integer& ErrorStatus)
{
Standard_Integer ii ;
if (IsPeriodic()) {
@@ -1071,24 +1086,26 @@ void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U,
delta_derivative) ;
gp_Vec delta(P0, P);
for (ii = 1 ; ii <= 3 ; ii++) {
delta_derivative.SetCoord(ii, Tangent.Coord(ii)-delta_derivative.Coord(ii));
delta_derivative.SetCoord(ii,
Tangent.Coord(ii)- delta_derivative.Coord(ii)) ;
}
BSplCLib::MovePointAndTangent(U,
delta,
delta_derivative,
Tolerance,
deg,
rational,
StartingCondition,
EndingCondition,
poles->Array1(),
weights->Array1(),
flatknots->Array1(),
new_poles,
ErrorStatus) ;
delta,
delta_derivative,
Tolerance,
deg,
rational,
StartingCondition,
EndingCondition,
poles->Array1(),
weights->Array1(),
flatknots->Array1(),
new_poles,
ErrorStatus) ;
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1102,11 +1119,11 @@ void Geom_BSplineCurve::UpdateKnots()
rational = !weights.IsNull();
Standard_Integer MaxKnotMult = 0;
BSplCLib::KnotAnalysis(deg,
periodic,
knots->Array1(),
mults->Array1(),
knotSet, MaxKnotMult);
BSplCLib::KnotAnalysis (deg,
periodic,
knots->Array1(),
mults->Array1(),
knotSet, MaxKnotMult);
if (knotSet == GeomAbs_Uniform && !periodic) {
flatknots = knots;
@@ -1115,10 +1132,10 @@ void Geom_BSplineCurve::UpdateKnots()
flatknots = new TColStd_HArray1OfReal
(1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
BSplCLib::KnotSequence(knots->Array1(),
mults->Array1(),
deg,periodic,
flatknots->ChangeArray1());
BSplCLib::KnotSequence (knots->Array1(),
mults->Array1(),
deg,periodic,
flatknots->ChangeArray1());
}
if (MaxKnotMult == 0) smooth = GeomAbs_CN;
@@ -1131,6 +1148,36 @@ void Geom_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : Invalidate the Cache
//purpose : as the name says
//=======================================================================
void Geom_BSplineCurve::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : check if the Cache is valid
//purpose : as the name says
//=======================================================================
Standard_Boolean Geom_BSplineCurve::IsCacheValid
(const Standard_Real U) const
{
//Roman Lygin 26.12.08, performance improvements
//1. avoided using NewParameter = (U - parametercache) / spanlenghtcache
//to check against [0, 1), as division is CPU consuming
//2. minimized use of if, as branching is also CPU consuming
Standard_Real aDelta = U - parametercache;
return ( validcache &&
(aDelta >= 0.0e0) &&
((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) );
}
//=======================================================================
@@ -1153,3 +1200,83 @@ void Geom_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const
}
}
//=======================================================================
//function : Validate the Cache
//purpose : that is compute the cache so that it is valid
//=======================================================================
void Geom_BSplineCurve::ValidateCache(const Standard_Real Parameter)
{
Standard_Real NewParameter ;
Standard_Integer LocalIndex = 0 ;
//
// check if the degree did not change
//
if (cachepoles->Upper() < deg + 1)
cachepoles = new TColgp_HArray1OfPnt(1,deg + 1);
if (rational)
{
if (cacheweights.IsNull() || cacheweights->Upper() < deg + 1)
cacheweights = new TColStd_HArray1OfReal(1,deg + 1);
}
else if (!cacheweights.IsNull())
cacheweights.Nullify();
BSplCLib::LocateParameter(deg,
(flatknots->Array1()),
(BSplCLib::NoMults()),
Parameter,
periodic,
LocalIndex,
NewParameter);
spanindexcache = LocalIndex ;
if (Parameter == flatknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
parametercache = flatknots->Value(LocalIndex) ;
if (LocalIndex == flatknots->Upper() - deg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// spanindexcache to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ;
}
else {
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
}
else {
parametercache = flatknots->Value(LocalIndex) ;
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
if (rational) {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
weights->Array1(),
cachepoles->ChangeArray1(),
cacheweights->ChangeArray1()) ;
}
else {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
*((TColStd_Array1OfReal*) NULL),
cachepoles->ChangeArray1(),
*((TColStd_Array1OfReal*) NULL)) ;
}
validcache = 1 ;
}

View File

@@ -30,6 +30,7 @@
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_Mutex.hxx>
#include <Precision.hxx>
#define POLES (poles->Array1())
@@ -180,24 +181,33 @@ Standard_Integer Geom_BSplineCurve::Degree () const
void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
cacheweights->Array1(),
P);
}
else
else
{
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P);
}
}
@@ -211,25 +221,36 @@ void Geom_BSplineCurve::D1 (const Standard_Real U,
gp_Pnt& P,
gp_Vec& V1) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1);
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
cacheweights->Array1(),
P,
V1);
}
else
else
{
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1);
P,
V1);
}
}
@@ -243,25 +264,37 @@ void Geom_BSplineCurve::D2(const Standard_Real U,
gp_Vec& V1,
gp_Vec& V2) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2);
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2);
}
else
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2);
else {
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2);
}
}
@@ -276,25 +309,41 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
gp_Vec& V2,
gp_Vec& V3) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2,
V3) ;
}
else
else
{
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2,
V3) ;
}
}
@@ -303,19 +352,19 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
//purpose :
//=======================================================================
gp_Vec Geom_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N) const
gp_Vec Geom_BSplineCurve::DN (const Standard_Real U,
const Standard_Integer N ) const
{
gp_Vec V;
if (rational) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(),
FKNOTS,FMULTS,V);
weights->Array1(),
FKNOTS,FMULTS,V);
}
else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
}
return V;
}
@@ -388,11 +437,6 @@ void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
{
return knots->Array1();
}
//=======================================================================
//function : KnotSequence
//purpose :
@@ -405,11 +449,6 @@ void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//=======================================================================
//function : LastUKnotIndex
//purpose :
@@ -629,11 +668,6 @@ void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//=======================================================================
//function : NbKnots
//purpose :
@@ -674,11 +708,6 @@ void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const
P = poles->Array1();
}
const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
{
return poles->Array1();
}
//=======================================================================
//function : StartPoint
//purpose :
@@ -728,13 +757,6 @@ void Geom_BSplineCurve::Weights
}
}
const TColStd_Array1OfReal& Geom_BSplineCurve::Weights() const
{
if (IsRational())
return weights->Array1();
return BSplCLib::NoWeights();
}
//=======================================================================
//function : IsRational
//purpose :
@@ -756,6 +778,7 @@ void Geom_BSplineCurve::Transform
TColgp_Array1OfPnt & CPoles = poles->ChangeArray1();
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
InvalidateCache() ;
maxderivinvok = 0;
}

View File

@@ -147,7 +147,8 @@ uses Array1OfInteger from TColStd,
BSplKnotDistribution from GeomAbs,
Curve from Geom,
Geometry from Geom,
Shape from GeomAbs
Shape from GeomAbs,
Mutex from Standard
raises ConstructionError from Standard,
DimensionError from Standard,
@@ -918,6 +919,16 @@ is
-- |1.0, 2.0, 0.5|
-- if Weights = |1.0, 2.0, 0.5| returns False
-- |1.0, 2.0, 0.5|
IsCacheValid(me; UParameter, VParameter : Real) returns Boolean ;
---Purpose :
-- Tells whether the Cache is valid for the
-- given parameter
-- Warnings : the parameter must be normalized within
-- the period if the curve is periodic. Otherwise
-- the answer will be false
--
Bounds (me; U1, U2, V1, V2 : out Real);
---Purpose :
@@ -1006,11 +1017,6 @@ is
---Purpose :
-- Raised if the length of P in the U and V direction
-- is not equal to NbUpoles and NbVPoles.
Poles (me)
returns Array2OfPnt from TColgp
---Purpose : Returns the poles of the B-spline surface.
---C++ : return const &
is static;
UDegree (me) returns Integer;
@@ -1049,11 +1055,6 @@ is
---Purpose :
-- Raised if the length of Ku is not equal to the number of knots
-- in the U direction.
UKnots (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots in the U direction.
---C++ : return const &
is static;
UKnotSequence (me; Ku : out Array1OfReal from TColStd)
@@ -1065,15 +1066,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of Ku is not equal to NbUPoles + UDegree + 1
UKnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the uknots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
--- Example :
-- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
UMultiplicity (me; UIndex : Integer) returns Integer
@@ -1091,11 +1083,6 @@ is
---Purpose :
-- Raised if the length of Mu is not equal to the number of
-- knots in the U direction.
UMultiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : Returns the multiplicities of the knots in the U direction.
---C++ : return const &
is static;
VDegree (me) returns Integer;
@@ -1133,11 +1120,6 @@ is
---Purpose :
-- Raised if the length of Kv is not equal to the number of
-- knots in the V direction.
VKnots (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots in the V direction.
---C++ : return const &
is static;
VKnotSequence (me; Kv : out Array1OfReal from TColStd)
@@ -1149,15 +1131,6 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of Kv is not equal to NbVPoles + VDegree + 1
VKnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the vknots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
--- Example :
-- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
VMultiplicity (me; VIndex : Integer) returns Integer
@@ -1175,11 +1148,6 @@ is
---Purpose :
-- Raised if the length of Mv is not equal to the number of
-- knots in the V direction.
VMultiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : Returns the multiplicities of the knots in the V direction.
---C++ : return const &
is static;
Weight (me; UIndex, VIndex : Integer) returns Real
@@ -1196,11 +1164,6 @@ is
---Purpose :
-- Raised if the length of W in the U and V direction is
-- not equal to NbUPoles and NbVPoles.
Weights (me)
returns Array2OfReal from TColStd
---Purpose : Returns the weights of the B-spline surface.
---C++ : return const &
is static;
@@ -1426,6 +1389,16 @@ is
is static private;
InvalidateCache(me : mutable)
---Purpose : Invalidates the cache. This has to be private this has to be private
is static private;
ValidateCache(me : mutable ; UParameter : Real;
VParameter : Real)
is static private;
---Purpose : updates the cache and validates it
fields
@@ -1447,8 +1420,68 @@ fields
vknots : HArray1OfReal from TColStd;
umults : HArray1OfInteger from TColStd;
vmults : HArray1OfInteger from TColStd;
umaxderivinv : Real from Standard;
vmaxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
-- Inplementation of the cache on surfaces
cachepoles : HArray2OfPnt from TColgp;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1]x[0 1]. The Taylor expension of lower degree
-- is stored as consecutive Pnt in the array that is
-- if udeg <= vdeg than the array stores the following
--
-- (2,0) (3,0)
-- (1,0) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- (2,1) (3,1)
-- (0,1) (1,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- Otherwise it is stored in the following fashion
--
--
-- (0,2) (0,3)
-- (0,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- (1,2) (1,3)
-- (1,0) (1,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- The size of the array is (1,Max degree) (1, Min degree)
--
cacheweights : HArray2OfReal from TColStd;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1]x[0 1]. The Taylor expension of lower degree
-- is stored as consecutive Real in the array as explained above
ucacheparameter : Real ;
vcacheparameter : Real ;
-- Parameters at which the Taylor expension is stored in
-- the cache
ucachespanlenght : Real ;
vcachespanlenght : Real ;
-- Since the Taylor expansion is normalized in the
-- cache to evaluate the cache one has to use
-- (UParameter - uparametercache) / ucachespanlenght
-- (VParameter - vparametercache) / vcachespanlenght
ucachespanindex : Integer ;
vcachespanindex : Integer ;
-- the span for which the cache is valid if
-- validcache is 1
validcache : Integer ;
-- usefull to evaluate the parametric resolutions
umaxderivinv : Real from Standard;
vmaxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bsplinesurface-cache
end;

View File

@@ -165,6 +165,8 @@ Geom_BSplineSurface::Geom_BSplineSurface
maxderivinvok(0)
{
Standard_Integer MinDegree,
MaxDegree ;
// check
@@ -194,6 +196,19 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1) ;
cacheweights.Nullify() ;
ucacheparameter = 0.0e0 ;
vcacheparameter = 0.0e0 ;
ucachespanlenght = 1.0e0 ;
vcachespanlenght = 1.0e0 ;
ucachespanindex = 0 ;
vcachespanindex = 0 ;
validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
@@ -223,6 +238,8 @@ Geom_BSplineSurface::Geom_BSplineSurface
vdeg(VDegree),
maxderivinvok(0)
{
Standard_Integer MinDegree,
MaxDegree ;
// check weights
if (Weights.ColLength() != Poles.ColLength())
@@ -272,6 +289,21 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1) ;
if (urational || vrational) {
cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1,
1,MinDegree + 1);
}
ucacheparameter = 0.0e0 ;
vcacheparameter = 0.0e0 ;
ucachespanlenght = 1.0e0 ;
vcachespanlenght = 1.0e0 ;
ucachespanindex = 0 ;
vcachespanindex = 0 ;
validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
@@ -1226,6 +1258,8 @@ void Geom_BSplineSurface::UpdateUKnots()
default : Usmooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
@@ -1264,8 +1298,18 @@ void Geom_BSplineSurface::UpdateVKnots()
default : Vsmooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : InvalidateCache
//purpose : Invalidates the Cache of the surface
//=======================================================================
void Geom_BSplineSurface::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : Normalizes the parameters if the curve is periodic
@@ -1318,6 +1362,177 @@ void Geom_BSplineSurface::PeriodicNormalization
}
}
//=======================================================================
//function : ValidateCache
//purpose : function that validates the cache of the surface
//=======================================================================
void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter,
const Standard_Real Vparameter)
{
Standard_Real NewParameter ;
Standard_Integer LocalIndex = 0 ;
Standard_Integer MinDegree,
MaxDegree ;
//
// check if the degree did not change
//
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
if (cachepoles->ColLength() < MaxDegree + 1 ||
cachepoles->RowLength() < MinDegree + 1) {
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1);
}
//
// Verif + poussee pour les poids
//
if (urational || vrational) {
if (cacheweights.IsNull()) {
cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1,MinDegree + 1);
}
else {
if (cacheweights->ColLength() < MaxDegree + 1 ||
cacheweights->RowLength() < MinDegree + 1) {
cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1,MinDegree + 1);
}
}
}
else if (!cacheweights.IsNull())
cacheweights.Nullify();
BSplCLib::LocateParameter(udeg,
(ufknots->Array1()),
(BSplCLib::NoMults()),
Uparameter,
uperiodic,
LocalIndex,
NewParameter);
ucachespanindex = LocalIndex ;
if (Uparameter == ufknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
ucacheparameter = ufknots->Value(LocalIndex) ;
if (LocalIndex == ufknots->Upper() - udeg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// cachespanindex to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ;
}
else {
ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
}
}
else {
ucacheparameter = ufknots->Value(LocalIndex) ;
ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
}
LocalIndex = 0 ;
BSplCLib::LocateParameter(vdeg,
(vfknots->Array1()),
(BSplCLib::NoMults()),
Vparameter,
vperiodic,
LocalIndex,
NewParameter);
vcachespanindex = LocalIndex ;
if (Vparameter == vfknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
vcacheparameter = vfknots->Value(LocalIndex) ;
if (LocalIndex == vfknots->Upper() - vdeg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// cachespanindex to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ;
}
else {
vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
}
}
else {
vcacheparameter = vfknots->Value(LocalIndex) ;
vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
}
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (urational || vrational) {
BSplSLib::BuildCache(uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
uperiodic,
vperiodic,
udeg,
vdeg,
ucachespanindex,
vcachespanindex,
(ufknots->Array1()),
(vfknots->Array1()),
poles->Array2(),
weights->Array2(),
cachepoles->ChangeArray2(),
cacheweights->ChangeArray2()) ;
}
else {
BSplSLib::BuildCache(uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
uperiodic,
vperiodic,
udeg,
vdeg,
ucachespanindex,
vcachespanindex,
(ufknots->Array1()),
(vfknots->Array1()),
poles->Array2(),
*((TColStd_Array2OfReal*) NULL),
cachepoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL)) ;
}
validcache = 1 ;
}
//=======================================================================
//function : IsCacheValid
//purpose : function that checks for the validity of the cache of the
// surface
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsCacheValid
(const Standard_Real U,
const Standard_Real V) const
{
//Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
Standard_Real aDeltaU = U - ucacheparameter;
Standard_Real aDeltaV = V - vcacheparameter;
return ( validcache &&
(aDeltaU >= 0.0e0) &&
((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) &&
(aDeltaV >= 0.0e0) &&
((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) );
}
//=======================================================================
//function : SetWeight
//purpose :
@@ -1335,6 +1550,7 @@ void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
}
Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
Rational(Weights, urational, vrational);
InvalidateCache();
}
//=======================================================================
@@ -1367,6 +1583,8 @@ void Geom_BSplineSurface::SetWeightCol
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
InvalidateCache();
}
//=======================================================================
@@ -1401,5 +1619,6 @@ void Geom_BSplineSurface::SetWeightRow
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
InvalidateCache();
}

View File

@@ -109,15 +109,48 @@ Standard_Boolean Geom_BSplineSurface::IsCNv
void Geom_BSplineSurface::D0(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P) const
gp_Pnt& P) const
{
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
BSplSLib::D0(aNewU,aNewV,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P);
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P) ;
}
else {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P) ;
}
}
//=======================================================================
@@ -127,25 +160,56 @@ void Geom_BSplineSurface::D0(const Standard_Real U,
void Geom_BSplineSurface::D1(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
Standard_Integer uindex = 0, vindex = 0;
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P, D1U, D1V);
if (cacheweights.IsNull()) {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V) ;
}
else {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V) ;
}
}
//=======================================================================
@@ -154,30 +218,64 @@ void Geom_BSplineSurface::D1(const Standard_Real U,
//=======================================================================
void Geom_BSplineSurface::D2 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
{
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
Standard_Integer uindex = 0, vindex = 0;
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P, D1U, D1V, D2U, D2V, D2UV);
}
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
else {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
}
//=======================================================================
//function : D3
@@ -444,11 +542,6 @@ void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const
P = poles->Array2();
}
const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const
{
return poles->Array2();
}
//=======================================================================
//function : UIso
//purpose :
@@ -552,11 +645,6 @@ void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const
Ku = uknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const
{
return uknots->Array1();
}
//=======================================================================
//function : VKnots
//purpose :
@@ -568,11 +656,6 @@ void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const
Kv = vknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const
{
return vknots->Array1();
}
//=======================================================================
//function : UKnotSequence
//purpose :
@@ -584,11 +667,6 @@ void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const
Ku = ufknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const
{
return ufknots->Array1();
}
//=======================================================================
//function : VKnotSequence
//purpose :
@@ -600,11 +678,6 @@ void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const
Kv = vfknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const
{
return vfknots->Array1();
}
//=======================================================================
//function : UMultiplicity
//purpose :
@@ -628,11 +701,6 @@ void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const
Mu = umults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const
{
return umults->Array1();
}
//=======================================================================
//function : VIso
//purpose :
@@ -730,11 +798,6 @@ void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const
Mv = vmults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const
{
return vmults->Array1();
}
//=======================================================================
//function : Weight
//purpose :
@@ -763,13 +826,6 @@ void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const
W = weights->Array2();
}
const TColStd_Array2OfReal& Geom_BSplineSurface::Weights() const
{
if (urational || vrational)
return weights->Array2();
return BSplSLib::NoWeights();
}
//=======================================================================
//function : Transform
//purpose :
@@ -783,6 +839,8 @@ void Geom_BSplineSurface::Transform (const gp_Trsf& T)
VPoles (i, j).Transform (T);
}
}
InvalidateCache();
}
//=======================================================================
@@ -1497,6 +1555,8 @@ void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
}
InvalidateCache();
}
//=======================================================================
@@ -1533,6 +1593,8 @@ void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
}
InvalidateCache();
}
//=======================================================================
@@ -1558,6 +1620,7 @@ void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
const gp_Pnt& P)
{
poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
InvalidateCache();
}
//=======================================================================
@@ -1613,6 +1676,7 @@ void Geom_BSplineSurface::MovePoint(const Standard_Real U,
poles->ChangeArray2() = npoles;
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================

View File

@@ -39,7 +39,6 @@
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
typedef Geom_OffsetCurve OffsetCurve;
typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve);
@@ -63,13 +62,6 @@ static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true if the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(
const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1,
gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative);
//=======================================================================
@@ -327,8 +319,10 @@ void Geom_OffsetCurve::D2 (const Standard_Real U, Pnt& P, Vec& V1, Vec& V2) cons
//purpose :
//=======================================================================
void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec& theV2, Vec& theV3) const
{
void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& P, Vec& theV1, Vec& V2, Vec& V3)
const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
@@ -342,15 +336,137 @@ void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec&
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec aV4 = basisCurve->DN (theU, 4);
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, aV4);
basisCurve->D3 (theU, P, theV1, V2, V3);
Vec V4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
CSLib_Offset::D3(theP, theV1, theV2, theV3, aV4, direction, offsetValue,
IsDirectionChange, theP, theV1, theV2, theV3);
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex + 1);
V3 = -basisCurve->DN (theU, anIndex + 2);
V4 = -basisCurve->DN (theU, anIndex + 3);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex + 1);
V3 = basisCurve->DN (theU, anIndex + 2);
V4 = basisCurve->DN (theU, anIndex + 3);
}
}//if(V1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real R6 = R3 * R3;
Standard_Real R7 = R5 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
if (R7 <= gp::Resolution()) {
if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2));
D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 -
15.0*Dr*Dr*Dr/R6 - D3r));
D3Ndir.Multiply (offsetValue/R);
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec(D3Ndir));
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2)));
D2Ndir.Multiply (offsetValue / R);
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// V3 = P"' (U) :
D3Ndir.Divide (R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 -
15.0*Dr*Dr*Dr/R7 - D3r));
D3Ndir.Multiply (offsetValue);
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec(D3Ndir));
// V2 = P" (U) :
D2Ndir.Divide (R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3)));
D2Ndir.Multiply (offsetValue);
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec(DNdir));
}
//P (U) :
D0(theU,P);
}
@@ -392,13 +508,68 @@ Vec Geom_OffsetCurve::DN (const Standard_Real U, const Standard_Integer N) const
void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
gp_Pnt& thePbasis, gp_Vec& theV1basis)const
{
basisCurve->D1(theU, thePbasis, theV1basis);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, theV1basis);
{
const Standard_Real aTol = gp::Resolution();
CSLib_Offset::D0(thePbasis, theV1basis, direction, offsetValue, IsDirectionChange, theP);
basisCurve->D1 (theU, thePbasis, theV1basis);
Standard_Real Ndu = theV1basis.Magnitude();
if(Ndu <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
Ndu = V.Magnitude();
}
while((Ndu <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
gp_Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
theV1basis = -V;
else
theV1basis = V;
Ndu = theV1basis.Magnitude();
}//if(Ndu <= aTol)
XYZ Ndir = (theV1basis.XYZ()).Crossed (direction.XYZ());
Standard_Real R = Ndir.Modulus();
if (R <= gp::Resolution())
Geom_UndefinedValue::Raise("Exception: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Ndir.Multiply (offsetValue/R);
Ndir.Add (thePbasis.XYZ());
theP.SetXYZ(Ndir);
}
//=======================================================================
@@ -407,21 +578,96 @@ void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
//=======================================================================
void Geom_OffsetCurve::D1 ( const Standard_Real theU,
Pnt& theP , Pnt& thePBasis ,
Vec& theV1, Vec& theV1basis, Vec& theV2basis) const {
Pnt& P , Pnt& PBasis ,
Vec& theV1, Vec& V1basis, Vec& V2basis) const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
basisCurve->D2 (theU, thePBasis, theV1basis, theV2basis);
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1basis, theV2basis);
basisCurve->D2 (theU, PBasis, V1basis, V2basis);
theV1 = V1basis;
Vec V2 = V2basis;
CSLib_Offset::D1(thePBasis, theV1basis, theV2basis, direction, offsetValue, IsDirectionChange, theP, theV1);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = - basisCurve->DN (theU, anIndex+1);
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
}
V2basis = V2;
V1basis = theV1;
}//if(theV1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
if (R3 <= gp::Resolution()) {
//We try another computation but the stability is not very good.
if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue * Dr/R3));
theV1.Add (Vec(DNdir));
}
D0(theU,P);
}
@@ -430,11 +676,11 @@ void Geom_OffsetCurve::D1 ( const Standard_Real theU,
//purpose :
//=======================================================================
void Geom_OffsetCurve::D2 (const Standard_Real theU,
Pnt& theP, Pnt& thePBasis,
Vec& theV1, Vec& theV2,
Vec& theV1basis, Vec& theV2basis, Vec& theV3basis) const
{
void Geom_OffsetCurve::D2 (const Standard_Real theU,
Pnt& P , Pnt& PBasis ,
Vec& theV1 , Vec& V2 ,
Vec& V1basis, Vec& V2basis, Vec& V3basis) const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
@@ -443,15 +689,129 @@ void Geom_OffsetCurve::D2 (const Standard_Real theU,
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, thePBasis, theV1basis, theV2basis, theV3basis);
basisCurve->D3 (theU, PBasis, V1basis, V2basis, V3basis);
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1basis, theV2basis, theV3basis);
theV1 = V1basis;
V2 = V2basis;
Vec V3 = V3basis;
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
CSLib_Offset::D2(thePBasis, theV1basis, theV2basis, theV3basis, direction, offsetValue,
IsDirectionChange, theP, theV1, theV2);
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex+1);
V3 = -basisCurve->DN (theU, anIndex + 2);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
V3 = basisCurve->DN (theU, anIndex + 2);
}
V2basis = V2;
V1basis = theV1;
}//if(V1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution()) {
//We try another computation but the stability is not very good
//dixit ISG.
if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (offsetValue / R);
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Add (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
)
);
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec(DNdir));
}
//P (U) :
D0(theU,P);
}
@@ -569,57 +929,3 @@ GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec& theD1, gp_Vec& theD2,
gp_Vec& theD3, gp_Vec& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theCurve->FirstParameter();
const Standard_Real anUsupremum = theCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec V;
do
{
V = theCurve->DN(theU, ++anIndex);
}
while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt P1, P2;
theCurve->D0(Min(theU, u), P1);
theCurve->D0(Max(theU, u), P2);
gp_Vec V1(P1, P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -397,10 +397,6 @@ void Geom_SurfaceOfRevolution::D1
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
@@ -467,10 +463,6 @@ void Geom_SurfaceOfRevolution::D2
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
@@ -566,10 +558,6 @@ void Geom_SurfaceOfRevolution::D3
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
@@ -775,11 +763,6 @@ void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
@@ -835,11 +818,6 @@ void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
@@ -918,11 +896,6 @@ void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')

View File

@@ -124,7 +124,8 @@ uses Array1OfInteger from TColStd,
Vec2d from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom2d,
Shape from GeomAbs
Shape from GeomAbs,
Mutex from Standard
raises ConstructionError from Standard,
DimensionError from Standard,
@@ -641,6 +642,17 @@ is
-- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real.
IsCacheValid(me; Parameter : Real) returns Boolean
---Purpose :
-- Tells whether the Cache is valid for the
-- given parameter
-- Warnings : the parameter must be normalized within
-- the period if the curve is periodic. Otherwise
-- the answer will be false
--
is static private;
Continuity (me) returns Shape from GeomAbs;
--- Purpose :
-- Returns the global continuity of the curve :
@@ -831,11 +843,6 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of K is not equal to the number of knots.
Knots (me)
returns Array1OfReal from TColStd
---Purpose : returns the knot values of the B-spline curve;
---C++ : return const &
is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
@@ -847,15 +854,6 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of K is not equal to NbPoles + Degree + 1
KnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
-- Example :
-- K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
@@ -921,11 +919,6 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of M is not equal to NbKnots.
Multiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : returns the multiplicity of the knots of the curve.
---C++ : return const &
is static;
NbKnots (me) returns Integer;
@@ -949,11 +942,6 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of P is not equal to the number of poles.
Poles (me)
returns Array1OfPnt2d from TColgp
---Purpose : Returns the poles of the B-spline curve;
---C++ : return const &
is static;
StartPoint (me) returns Pnt2d;
@@ -975,11 +963,6 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of W is not equal to NbPoles.
Weights (me)
returns Array1OfReal from TColStd
---Purpose : Returns the weights of the B-spline curve;
---C++ : return const &
is static;
@@ -1013,8 +996,17 @@ is
UpdateKnots(me : mutable)
---Purpose: Recompute the flatknots, the knotsdistribution, the continuity.
is static private;
InvalidateCache(me : mutable)
---Purpose : Invalidates the cache. This has to be private this has to be private
is static private;
ValidateCache(me : mutable ; Parameter : Real)
is static private;
---Purpose : updates the cache and validates it
fields
rational : Boolean;
@@ -1027,7 +1019,35 @@ fields
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
cachepoles : HArray1OfPnt2d from TColgp;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
cacheweights : HArray1OfReal from TColStd;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
validcache : Integer;
-- = 1 the cache is valid
-- = 0 the cache is invalid
parametercache : Real;
-- Parameter at which the Taylor expension is stored in
-- the cache
spanlenghtcache : Real;
-- Since the Taylor expansion is normalized in the
-- cache to evaluate the cache one has to use
-- (Parameter - refcache) * normcache
spanindexcache : Integer;
-- the span for which the cache is valid if
-- validcache is 1
-- usefull to evaluate the parametric resolution
maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bspline-cache
end;

View File

@@ -123,11 +123,12 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
{
// check
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
// copy arrays
@@ -141,6 +142,10 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -164,11 +169,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
// check
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch");
@@ -187,9 +192,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
poles = new TColgp_HArray1OfPnt2d(1,Poles.Length());
poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
knots = new TColStd_HArray1OfReal(1,Knots.Length());
@@ -199,6 +206,10 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -1079,6 +1090,7 @@ void Geom2d_BSplineCurve::SetPole
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch");
poles->SetValue (Index, P);
maxderivinvok = 0;
InvalidateCache();
}
//=======================================================================
@@ -1128,6 +1140,7 @@ void Geom2d_BSplineCurve::SetWeight
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@@ -1136,11 +1149,11 @@ void Geom2d_BSplineCurve::SetWeight
//=======================================================================
void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt2d& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
const gp_Pnt2d& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
{
if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
@@ -1151,11 +1164,12 @@ void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0);
gp_Vec2d Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) {
poles->ChangeArray1() = npoles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1208,6 +1222,7 @@ MovePointAndTangent(const Standard_Real U,
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1251,6 +1266,33 @@ void Geom2d_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : Invalidate the Cache
//purpose : as the name says
//=======================================================================
void Geom2d_BSplineCurve::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : check if the Cache is valid
//purpose : as the name says
//=======================================================================
Standard_Boolean Geom2d_BSplineCurve::IsCacheValid
(const Standard_Real U) const
{
//Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
Standard_Real aDelta = U - parametercache;
return ( validcache &&
(aDelta >= 0.0e0) &&
((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) );
}
//=======================================================================
@@ -1273,3 +1315,83 @@ void Geom2d_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const
}
}
//=======================================================================
//function : Validate the Cache
//purpose : that is compute the cache so that it is valid
//=======================================================================
void Geom2d_BSplineCurve::ValidateCache(const Standard_Real Parameter)
{
Standard_Real NewParameter ;
Standard_Integer LocalIndex = 0 ;
//
// check if the degree did not change
//
if (cachepoles->Upper() < deg + 1)
cachepoles = new TColgp_HArray1OfPnt2d(1,deg + 1);
if (rational)
{
if (cacheweights.IsNull() || cacheweights->Upper() < deg + 1)
cacheweights = new TColStd_HArray1OfReal(1,deg + 1);
}
else if (!cacheweights.IsNull())
cacheweights.Nullify();
BSplCLib::LocateParameter(deg,
(flatknots->Array1()),
(BSplCLib::NoMults()),
Parameter,
periodic,
LocalIndex,
NewParameter);
spanindexcache = LocalIndex ;
if (Parameter == flatknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
parametercache = flatknots->Value(LocalIndex) ;
if (LocalIndex == flatknots->Upper() - deg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// spanindexcache to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ;
}
else {
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
}
else {
parametercache = flatknots->Value(LocalIndex) ;
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
if (rational) {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
weights->Array1(),
cachepoles->ChangeArray1(),
cacheweights->ChangeArray1()) ;
}
else {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
*((TColStd_Array1OfReal*) NULL),
cachepoles->ChangeArray1(),
*((TColStd_Array1OfReal*) NULL)) ;
}
validcache = 1 ;
}

View File

@@ -30,7 +30,7 @@
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
#include <Precision.hxx>
#include <Standard_Mutex.hxx>
#define POLES (poles->Array1())
#define KNOTS (knots->Array1())
@@ -183,28 +183,36 @@ Standard_Integer Geom2d_BSplineCurve::Degree () const
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D0(const Standard_Real U,
gp_Pnt2d& P) const
void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
gp_Pnt2d& P) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if (!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P);
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P) ;
}
else
{
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P);
else {
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P) ;
}
}
@@ -214,29 +222,39 @@ void Geom2d_BSplineCurve::D0(const Standard_Real U,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D1(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1) const
void Geom2d_BSplineCurve::D1 (const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if (!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1);
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1) ;
}
else
{
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1);
else {
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P,
V1) ;
}
}
@@ -245,30 +263,42 @@ void Geom2d_BSplineCurve::D1(const Standard_Real U,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D2(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1,
gp_Vec2d& V2) const
void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
gp_Pnt2d& P ,
gp_Vec2d& V1,
gp_Vec2d& V2 ) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if (!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2);
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2) ;
}
else
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2);
else {
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P,
V1,
V2) ;
}
}
@@ -277,31 +307,45 @@ void Geom2d_BSplineCurve::D2(const Standard_Real U,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D3(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1,
gp_Vec2d& V2,
gp_Vec2d& V3) const
void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
gp_Pnt2d& P ,
gp_Vec2d& V1,
gp_Vec2d& V2,
gp_Vec2d& V3 ) const
{
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if (!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2,
V3) ;
}
else
{
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
else {
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P,
V1,
V2,
V3) ;
}
}
@@ -310,20 +354,20 @@ void Geom2d_BSplineCurve::D3(const Standard_Real U,
//purpose :
//=======================================================================
gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N) const
gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U,
const Standard_Integer N ) const
{
gp_Vec2d V;
if ( rational ) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(),
FKNOTS,FMULTS,V);
weights->Array1(),
FKNOTS,FMULTS,V);
}
else {
else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
}
return V;
}
@@ -396,11 +440,6 @@ void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1();
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const
{
return knots->Array1();
}
//=======================================================================
//function : KnotSequence
//purpose :
@@ -413,11 +452,6 @@ void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1();
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//=======================================================================
//function : LastUKnotIndex
//purpose :
@@ -642,11 +676,6 @@ void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1();
}
const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//=======================================================================
//function : NbKnots
//purpose :
@@ -687,11 +716,6 @@ void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
P = poles->Array1();
}
const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const
{
return poles->Array1();
}
//=======================================================================
//function : StartPoint
//purpose :
@@ -740,13 +764,6 @@ void Geom2d_BSplineCurve::Weights
}
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::Weights() const
{
if (IsRational())
return weights->Array1();
return BSplCLib::NoWeights();
}
//=======================================================================
//function : IsRational
//purpose :
@@ -769,6 +786,7 @@ void Geom2d_BSplineCurve::Transform
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
InvalidateCache();
// maxderivinvok = 0;
}

View File

@@ -23,7 +23,6 @@
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_Line.hxx>
@@ -55,14 +54,6 @@ static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true if the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
//=======================================================================
//function : Copy
//purpose :
@@ -220,38 +211,163 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP) const
void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP ) const
{
const Standard_Real aTol = gp::Resolution();
Vec2d vD1;
basisCurve->D1 (theU, theP, vD1);
Standard_Real Ndu = vD1.Magnitude();
Standard_Boolean IsDirectionChange = Standard_False;
if(vD1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1);
if(Ndu <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP);
}
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = basisCurve->DN(theU,++anIndex);
Ndu = V.Magnitude();
}
while((Ndu <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
vD1 = -V;
else
vD1 = V;
Ndu = vD1.Magnitude();
}//if(Ndu <= aTol)
if (Ndu <= aTol)
Geom2d_UndefinedValue::Raise("Exception: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Standard_Real A = vD1.Y();
Standard_Real B = - vD1.X();
A = A * offsetValue/Ndu;
B = B * offsetValue/Ndu;
theP.SetCoord(theP.X() + A, theP.Y() + B);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1) const
{
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
const Standard_Real aTol = gp::Resolution();
Vec2d V2;
basisCurve->D2 (theU, theP, theV1, V2);
basisCurve->D2 (theU, P, theV1, V2);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2);
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = - basisCurve->DN (theU, anIndex+1);
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
}
}//if(theV1.Magnitude() <= aTol)
CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1);
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
if (R3 <= gp::Resolution()) {
//We try another computation but the stability is not very good.
if (R2 <= gp::Resolution()) Geom2d_UndefinedDerivative::Raise();
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec2d(DNdir));
}
D0(theU, P);
}
//=======================================================================
@@ -260,8 +376,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1
//=======================================================================
void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2) const
Pnt2d& P,
Vec2d& theV1, Vec2d& V2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
@@ -272,13 +388,124 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
Vec2d V3;
basisCurve->D3 (theU, theP, theV1, theV2, V3);
basisCurve->D3 (theU, P, theV1, V2, V3);
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3);
CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex+1);
V3 = -basisCurve->DN (theU, anIndex + 2);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
V3 = basisCurve->DN (theU, anIndex + 2);
}
}//if(V1.Magnitude() <= aTol)
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution())
{
//We try another computation but the stability is not very good
//dixit ISG.
if (R4 <= gp::Resolution())
{
Geom2d_UndefinedDerivative::Raise();
}
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (offsetValue / R);
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(DNdir));
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Add (Ndir.Multiplied
(offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U)
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec2d(DNdir));
}
//P (U) :
D0(theU, P);
}
@@ -288,9 +515,9 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
//=======================================================================
void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const
{
Pnt2d& P,
Vec2d& theV1, Vec2d& V2, Vec2d& V3) const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
@@ -305,16 +532,149 @@ void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec2d V4 = basisCurve->DN (theU, 4);
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4);
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange,
theP, theV1, theV2, theV3);
}
basisCurve->D3 (theU, P, theV1, V2, V3);
Vec2d V4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex + 1);
V3 = -basisCurve->DN (theU, anIndex + 2);
V4 = -basisCurve->DN (theU, anIndex + 3);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex + 1);
V3 = basisCurve->DN (theU, anIndex + 2);
V4 = basisCurve->DN (theU, anIndex + 3);
}
}//if(V1.Magnitude() <= aTol)
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
XY D3Ndir (V4.Y(), -V4.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real R6 = R3 * R3;
Standard_Real R7 = R5 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
if (R7 <= gp::Resolution())
{
//We try another computation but the stability is not very good
//dixit ISG.
if (R6 <= gp::Resolution())
Geom2d_UndefinedDerivative::Raise();
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R2));
D3Ndir.Subtract (
(DNdir.Multiplied ((3.0 * offsetValue) * ((D2r/R2) + (Dr*Dr)/R4))));
D3Ndir.Add (Ndir.Multiplied (
(offsetValue * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r))));
D3Ndir.Multiply (offsetValue/R);
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec2d(D3Ndir));
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (offsetValue / R);
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(DNdir));
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V3 = P"' (U) :
D3Ndir.Multiply (offsetValue/R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied (
((3.0 * offsetValue) * ((D2r/R3) + (Dr*Dr)/R5))) );
D3Ndir.Add (Ndir.Multiplied (
(offsetValue * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))));
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec2d(D3Ndir));
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec2d(DNdir));
}
//P (U) :
D0(theU, P);
}
//=======================================================================
//function : DN
@@ -349,10 +709,10 @@ Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1."
void Geom2d_OffsetCurve::Value (const Standard_Real theU,
Pnt2d& theP, Pnt2d& thePbasis,
Vec2d& theV1basis ) const
{
{
basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP);
}
}
//=======================================================================
@@ -381,8 +741,30 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real U,
if (Index != 2) {
V2 = basisCurve->DN (U, Index);
}
CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1);
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
if (R3 <= gp::Resolution()) {
//We try another computation but the stability is not very good.
if (R2 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue / R2);
V1.Add (Vec2d(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
V1.Add (Vec2d(DNdir));
}
Ndir.Multiply (offsetValue/R);
Ndir.Add (Pbasis.XY());
P.SetXY (Ndir);
}
@@ -418,8 +800,52 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real U,
V2 = basisCurve->DN (U, Index);
V3 = basisCurve->DN (U, Index + 1);
}
CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2);
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution()) {
//We try another computation but the stability is not very good
//dixit ISG.
if (R4 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (offsetValue / R);
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
V1.Add (Vec2d(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
)
);
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
V1.Add (Vec2d(DNdir));
}
//P (U) :
Ndir.Multiply (offsetValue/R);
Ndir.Add (Pbasis.XY());
P.SetXY (Ndir);
}
//=======================================================================
@@ -535,57 +961,3 @@ GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2,
gp_Vec2d& theD3, gp_Vec2d& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theCurve->FirstParameter();
const Standard_Real anUsupremum = theCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = theCurve->DN(theU, ++anIndex);
}
while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
theCurve->D0(Min(theU, u),P1);
theCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -27,8 +27,7 @@ uses
gp,
Standard,
TColStd,
TColgp,
BSplCLib
TColgp
is

View File

@@ -33,8 +33,7 @@ uses Vec2d from gp,
BSplineCurve from Geom2d,
CurveType from GeomAbs,
Shape from GeomAbs,
HCurve2d from Adaptor2d,
Cache from BSplCLib
HCurve2d from Adaptor2d
raises NoSuchObject from Standard,
@@ -124,44 +123,19 @@ is
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
ValueBSpline(me; U: Real) returns Pnt2d from gp
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
ValueOffset(me; U: Real) returns Pnt2d from gp
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D0 (me; U : Real; P : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
D0BSpline(me; theU : Real; theP : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
D0Offset(me; theU : Real; theP : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D1 (me; U : Real; P : out Pnt2d from gp ; V : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the curve with its
-- first derivative.
raises
DomainError from Standard
--- Purpose : Raised if the continuity of the current interval
-- is not C1.
is redefined static;
D1BSpline(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its derivative
is private;
D1Offset(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its derivative
is private;
D2 (me; U : Real; P : out Pnt2d from gp; V1, V2 : out Vec2d from gp)
--- Purpose :
@@ -173,16 +147,6 @@ is
-- is not C2.
is redefined static;
D2BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first and second derivatives
is private;
D2Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first and second derivatives
is private;
D3 (me; U : Real; P : out Pnt2d from gp; V1, V2, V3 : out Vec2d from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
@@ -192,16 +156,6 @@ is
--- Purpose : Raised if the continuity of the current interval
-- is not C3.
is redefined static;
D3BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first, second and third derivatives
is private;
D3Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first, second and third derivatives
is private;
DN (me; U : Real; N : Integer) returns Vec2d from gp
--- Purpose :
@@ -215,18 +169,6 @@ is
--- Purpose : Raised if N < 1.
is redefined static;
DNBSpline(me; theU : Real; N : Integer) returns Vec2d from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
DNOffset(me; theU : Real; N : Integer) returns Vec2d from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
Resolution(me; Ruv :Real) returns Real
---Purpose : returns the parametric resolution
@@ -301,11 +243,6 @@ is
load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real)
is private;
RebuildCache(me; theParameter : Real)
---Purpose: Rebuilds B-spline cache
-- \param theParameter the value on the knot axis which identifies the caching span
is static private;
fields
@@ -313,8 +250,6 @@ fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve2d from Adaptor2d;
end Curve;

View File

@@ -26,7 +26,6 @@
#include <Geom2dAdaptor_HCurve.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
@@ -43,9 +42,6 @@
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <CSLib_Offset.hxx>
//#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
#include <Standard_OutOfRange.hxx>
@@ -56,17 +52,6 @@
#define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true is the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
@@ -212,16 +197,6 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
}
else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
// Create cache for B-spline
myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
{
myTypeCurve = GeomAbs_OtherCurve;
// Create nested adaptor for base curve
Handle(Geom2d_Curve) aBase = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve();
myOffsetBaseCurveAdaptor = new Geom2dAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
@@ -243,7 +218,7 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
if (myTypeCurve == GeomAbs_BSplineCurve) {
return LocalContinuity(myFirst, myLast);
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
GeomAbs_Shape S =
(*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity();
switch(S){
@@ -355,7 +330,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
}
}
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
@@ -367,7 +342,9 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
Geom2dAdaptor_Curve C
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
myNbIntervals = C.NbIntervals(BaseS);
}
return myNbIntervals;
@@ -470,7 +447,7 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
}
}
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
@@ -482,8 +459,10 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
myOffsetBaseCurveAdaptor->Intervals(T, BaseS);
Geom2dAdaptor_Curve C
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
myNbIntervals = C.NbIntervals(BaseS);
C.Intervals(T, BaseS);
}
T( T.Lower() ) = myFirst;
@@ -546,17 +525,6 @@ Standard_Real Geom2dAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
{
myCurveCache->BuildCache(theParameter, myBspl->Degree(),
myBspl->IsPeriodic(), myBspl->KnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@@ -564,65 +532,24 @@ void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
return ValueBSpline(U);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
return ValueOffset(U);
return myCurve->Value(U);
}
//=======================================================================
//function : ValueBSpline
//purpose : Computes the point of parameter U on the B-spline curve
//=======================================================================
gp_Pnt2d Geom2dAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst)
{
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast)
{
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalValue(theU, Ideb, Ifin);
return myBspl->LocalValue(U, Ideb, Ifin);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
gp_Pnt2d aRes;
myCurveCache->D0(theU, aRes);
return aRes;
else {
return myCurve->Value( U);
}
return myCurve->Value(theU);
}
//=======================================================================
//function : ValueOffset
//purpose : Computes the point of parameter U on the offset curve
//=======================================================================
gp_Pnt2d Geom2dAdaptor_Curve::ValueOffset(const Standard_Real theU) const
{
gp_Pnt2d aP;
gp_Vec2d aD1;
myOffsetBaseCurveAdaptor->D1(theU, aP, aD1);
Standard_Boolean isDirectionChange = Standard_False;
const Standard_Real aTol = gp::Resolution();
if(aD1.SquareMagnitude() <= aTol)
isDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aD1);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D0(aP, aD1, anOffset, isDirectionChange, aP);
return aP;
}
//=======================================================================
@@ -632,59 +559,24 @@ gp_Pnt2d Geom2dAdaptor_Curve::ValueOffset(const Standard_Real theU) const
void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D0BSpline(U, P);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D0Offset(U, P);
return;
}
myCurve->D0(U, P);
}
//=======================================================================
//function : D0BSpline
//purpose : Computes the point of parameter theU on the B-spline curve
//=======================================================================
void Geom2dAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt2d& theP) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
myBspl->LocalD0( U, Ideb, Ifin, P);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D0(theU, theP);
return;
}
myCurve->D0(theU, theP);
}
//=======================================================================
//function : D0Offset
//purpose : Computes the point of parameter theU on the offset curve
//=======================================================================
void Geom2dAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt2d& theP) const
{
theP = ValueOffset(theU);
else {
myCurve->D0(U, P);
}
}
//=======================================================================
@@ -692,75 +584,27 @@ void Geom2dAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt2d& theP) con
//purpose :
//=======================================================================
void Geom2dAdaptor_Curve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V) const
void Geom2dAdaptor_Curve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D1BSpline(U, P, V);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D1Offset(U, P, V);
return;
}
myCurve->D1(U, P, V);
}
//=======================================================================
//function : D1BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its derivative
//=======================================================================
void Geom2dAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
return;
myBspl->LocalD1( U, Ideb, Ifin, P, V);
}
else {
myCurve->D1( U, P, V);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D1(theU, theP, theV);
return;
}
myCurve->D1(theU, theP, theV);
}
//=======================================================================
//function : D1Offset
//purpose : Computes the point of parameter theU on the offset curve and its derivative
//=======================================================================
void Geom2dAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
gp_Vec2d V2;
myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, V2);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, V2);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D1(theP, theV, V2, anOffset, IsDirectionChange, theP, theV);
}
//=======================================================================
@@ -769,78 +613,26 @@ void Geom2dAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt2d& theP, gp_
//=======================================================================
void Geom2dAdaptor_Curve::D2(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D2BSpline(U, P, V1, V2);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D2Offset(U, P, V1, V2);
return;
}
myCurve->D2(U, P, V1, V2);
}
//=======================================================================
//function : D2BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its first and second derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D2(theU, theP, theV1, theV2);
return;
else {
myCurve->D2( U, P, V1, V2);
}
myCurve->D2(theU, theP, theV1, theV2);
}
//=======================================================================
//function : D2Offset
//purpose : Computes the point of parameter theU on the offset curve and its first and second derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_Vec2d V3;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D2(theP, theV1, theV2, V3, anOffset, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
@@ -849,86 +641,27 @@ void Geom2dAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt2d& theP,
//=======================================================================
void Geom2dAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V3) const
gp_Pnt2d& P, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V3) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D3BSpline(U, P, V1, V2, V3);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D3Offset(U, P, V1, V2, V3);
return;
}
myCurve->D3(U, P, V1, V2, V3);
}
//=======================================================================
//function : D3BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its 1st - 3rd derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D3BSpline(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
return;
myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D3(theU, theP, theV1, theV2, theV3);
return;
else {
myCurve->D3( U, P, V1, V2, V3);
}
myCurve->D3(theU, theP, theV1, theV2, theV3);
}
//=======================================================================
//function : D3Offset
//purpose : Computes the point of parameter theU on the offset curve and its 1st - 3rd derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D3Offset(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
//P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
// (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
Standard_Boolean IsDirectionChange = Standard_False;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
gp_Vec2d V4 = myOffsetBaseCurveAdaptor->DN (theU, 4);
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffset, IsDirectionChange,
theP, theV1, theV2, theV3);
}
//=======================================================================
@@ -937,21 +670,10 @@ void Geom2dAdaptor_Curve::D3Offset(const Standard_Real theU, gp_Pnt2d& theP,
//=======================================================================
gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const
const Standard_Integer N) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
return DNBSpline(U, N);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
return DNOffset(U, N);
return myCurve->DN(U, N);
}
gp_Vec2d Geom2dAdaptor_Curve::DNBSpline(const Standard_Real U,
const Standard_Integer N) const
{
if (U==myFirst || U==myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
@@ -964,32 +686,10 @@ gp_Vec2d Geom2dAdaptor_Curve::DNBSpline(const Standard_Real U,
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
}
else {
return myCurve->DN( U, N);
}
return myCurve->DN( U, N);
}
gp_Vec2d Geom2dAdaptor_Curve::DNOffset(const Standard_Real U,
const Standard_Integer N) const
{
gp_Pnt2d aPnt;
gp_Vec2d aVec, aVN;
switch (N)
{
case 1:
D1Offset(U, aPnt, aVN);
break;
case 2:
D2Offset(U, aPnt, aVec, aVN);
break;
case 3:
D3Offset(U, aPnt, aVec, aVec, aVN);
break;
default:
aVN = myCurve->DN(U, N);
}
return aVN;
}
//=======================================================================
@@ -1206,57 +906,3 @@ Standard_Integer Geom2dAdaptor_Curve::NbSamples() const
{
return nbPoints(myCurve);
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2,
gp_Vec2d& theD3, gp_Vec2d& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theAdaptor->FirstParameter();
const Standard_Real anUsupremum = theAdaptor->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec2d V;
do
{
V = theAdaptor->DN(theU, ++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt2d P1, P2;
theAdaptor->D0(Min(theU, u),P1);
theAdaptor->D0(Max(theU, u),P2);
gp_Vec2d V1(P1, P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theAdaptor->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -28,9 +28,7 @@ uses
TColStd,
Geom2dAdaptor,
TColgp,
Precision,
BSplCLib,
BSplSLib
Precision
is
class Curve;

View File

@@ -33,8 +33,7 @@ uses Vec from gp,
BSplineCurve from Geom,
CurveType from GeomAbs,
Shape from GeomAbs,
HCurve from Adaptor3d,
Cache from BSplCLib
HCurve from Adaptor3d
raises NoSuchObject from Standard,
ConstructionError from Standard,
@@ -130,26 +129,10 @@ is
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
ValueBSpline(me; U: Real) returns Pnt from gp
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
ValueOffset(me; U: Real) returns Pnt from gp
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D0 (me; U : Real; P : out Pnt from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
D0BSpline(me; theU : Real; theP : out Pnt from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
D0Offset(me; theU : Real; theP : out Pnt from gp)
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp)
--- Purpose : Computes the point of parameter U on the curve
-- with its first derivative.
@@ -159,16 +142,6 @@ is
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
D1BSpline(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its derivative
is private;
D1Offset(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its derivative
is private;
D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp)
--- Purpose :
@@ -181,16 +154,6 @@ is
-- else the derivatives are computed on the basis curve.
is redefined static;
D2BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first and second derivatives
is private;
D2Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first and second derivatives
is private;
D3 (me; U : Real; P : out Pnt from gp; V1, V2, V3 : out Vec from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
@@ -201,16 +164,6 @@ is
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
D3BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first, second and third derivatives
is private;
D3Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first, second and third derivatives
is private;
DN (me; U : Real; N : Integer) returns Vec from gp
--- Purpose :
@@ -226,19 +179,6 @@ is
is redefined static;
DNBSpline(me; theU : Real; N : Integer) returns Vec from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
DNOffset(me; theU : Real; N : Integer) returns Vec from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
Resolution(me; R3d :Real) returns Real
---Purpose : returns the parametric resolution
is redefined static;
@@ -339,11 +279,6 @@ is
load(me : in out; C : Curve from Geom; UFirst,ULast : Real)
is private;
RebuildCache(me; theParameter : Real)
---Purpose: Rebuilds B-spline cache
-- \param theParameter the value on the knot axis which identifies the caching span
is static private;
fields
@@ -351,8 +286,6 @@ fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve from Adaptor3d;
friends
class Surface from GeomAdaptor

View File

@@ -26,7 +26,6 @@
#include <GeomAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
@@ -49,22 +48,10 @@
#include <Standard_NullObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Geom_OffsetCurve.hxx>
#include <CSLib_Offset.hxx>
#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true if the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(
const Handle(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1,
gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative);
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
@@ -168,15 +155,6 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
}
else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
// Create cache for B-spline
myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
myTypeCurve = GeomAbs_OtherCurve;
// Create nested adaptor for base curve
Handle(Geom_Curve) aBase = Handle(Geom_OffsetCurve)::DownCast(myCurve)->BasisCurve();
myOffsetBaseCurveAdaptor = new GeomAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
@@ -532,17 +510,6 @@ Standard_Real GeomAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
{
myCurveCache->BuildCache(theParameter, myBspl->Degree(),
myBspl->IsPeriodic(), myBspl->KnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@@ -550,64 +517,22 @@ void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
return ValueBSpline(U);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
return ValueOffset(U);
return myCurve->Value(U);
}
//=======================================================================
//function : ValueBSpline
//purpose :
//=======================================================================
gp_Pnt GeomAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalValue(theU, Ideb, Ifin);
return myBspl->LocalValue(U, Ideb, Ifin);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
gp_Pnt aRes;
myCurveCache->D0(theU, aRes);
return aRes;
}
return myCurve->Value(theU);
}
//=======================================================================
//function : ValueOffset
//purpose :
//=======================================================================
gp_Pnt GeomAdaptor_Curve::ValueOffset(const Standard_Real theU) const
{
gp_Pnt aP;
gp_Vec aV;
myOffsetBaseCurveAdaptor->D1(theU, aP, aV);
Standard_Boolean IsDirectionChange = Standard_False;
if(aV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aV);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D0(aP, aV, anOffsetDir, anOffsetVal, IsDirectionChange, aP);
return aP;
return myCurve->Value(U);
}
//=======================================================================
@@ -617,53 +542,24 @@ gp_Pnt GeomAdaptor_Curve::ValueOffset(const Standard_Real theU) const
void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
D0BSpline(U, P);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D0Offset(U, P);
else
myCurve->D0(U, P);
}
//=======================================================================
//function : D0BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt& theP) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
myBspl->LocalD0( U, Ideb, Ifin, P);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D0(theU, theP);
return;
}
myCurve->D0(theU, theP);
}
//=======================================================================
//function : D0Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt& theP) const
{
theP = ValueOffset(theU);
else {
myCurve->D0(U, P);
}
}
//=======================================================================
@@ -673,133 +569,52 @@ void GeomAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt& theP) const
void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
D1BSpline(U, P, V);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D1Offset(U, P, V);
else
myCurve->D1(U, P, V);
}
//=======================================================================
//function : D1BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
return;
myBspl->LocalD1( U, Ideb, Ifin, P, V);
}
else {
myCurve->D1( U, P, V);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D1(theU, theP, theV);
return;
}
myCurve->D1(theU, theP, theV);
}
//=======================================================================
//function : D1Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
{
gp_Vec aV2;
myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, aV2);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, aV2);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D1(theP, theV, aV2, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV);
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2(const Standard_Real U,
gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
D2BSpline(U, P, V1, V2);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D2Offset(U, P, V1, V2);
else
myCurve->D2(U, P, V1, V2);
}
//=======================================================================
//function : D2BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt& theP,
gp_Vec& theV1, gp_Vec& theV2) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D2(theU, theP, theV1, theV2);
return;
else {
myCurve->D2( U, P, V1, V2);
}
myCurve->D2(theU, theP, theV1, theV2);
}
//=======================================================================
//function : D2Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt& theP,
gp_Vec& theV1, gp_Vec& theV2) const
{
gp_Vec V3;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D2(theP, theV1, theV2, V3, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
@@ -808,71 +623,27 @@ void GeomAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt& theP,
//=======================================================================
void GeomAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt& P, gp_Vec& V1,
gp_Vec& V2, gp_Vec& V3) const
gp_Pnt& P, gp_Vec& V1,
gp_Vec& V2, gp_Vec& V3) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
D3BSpline(U, P, V1, V2, V3);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D3Offset(U, P, V1, V2, V3);
else
myCurve->D3(U, P, V1, V2, V3);
}
//=======================================================================
//function : D3BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D3BSpline(const Standard_Real theU,
gp_Pnt& theP, gp_Vec& theV1,
gp_Vec& theV2, gp_Vec& theV3) const
{
if (theU == myFirst || theU == myLast)
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (theU == myFirst) {
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (theU == myLast) {
if (U==myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
return;
myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D3(theU, theP, theV1, theV2, theV3);
return;
else {
myCurve->D3( U, P, V1, V2, V3);
}
myCurve->D3(theU, theP, theV1, theV2, theV3);
}
//=======================================================================
//function : D3Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D3Offset(const Standard_Real theU,
gp_Pnt& theP, gp_Vec& theV1,
gp_Vec& theV2, gp_Vec& theV3) const
{
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
gp_Vec V4 = myOffsetBaseCurveAdaptor->DN(theU, 4);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffsetDir, anOffsetVal, IsDirectionChange,
theP, theV1, theV2, theV3);
}
//=======================================================================
@@ -881,21 +652,10 @@ void GeomAdaptor_Curve::D3Offset(const Standard_Real theU,
//=======================================================================
gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const
const Standard_Integer N) const
{
if (myTypeCurve == GeomAbs_BSplineCurve)
return DNBSpline(U, N);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
return DNOffset(U, N);
return myCurve->DN(U, N);
}
gp_Vec GeomAdaptor_Curve::DNBSpline(const Standard_Real U,
const Standard_Integer N) const
{
if ((U==myFirst || U==myLast))
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
@@ -908,31 +668,10 @@ gp_Vec GeomAdaptor_Curve::DNBSpline(const Standard_Real U,
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
}
else {
return myCurve->DN( U, N);
}
return myCurve->DN( U, N);
}
gp_Vec GeomAdaptor_Curve::DNOffset(const Standard_Real U,
const Standard_Integer N) const
{
gp_Pnt aPnt;
gp_Vec aVec, aVN;
switch (N)
{
case 1:
D1Offset(U, aPnt, aVN);
break;
case 2:
D2Offset(U, aPnt, aVec, aVN);
break;
case 3:
D3Offset(U, aPnt, aVec, aVec, aVN);
break;
default:
aVN = myCurve->DN(U, N);
}
return aVN;
}
//=======================================================================
@@ -1118,56 +857,3 @@ Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
return *((Handle(Geom_BSplineCurve)*)&myCurve);
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec& theD1, gp_Vec& theD2,
gp_Vec& theD3, gp_Vec& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theAdaptor->FirstParameter();
const Standard_Real anUsupremum = theAdaptor->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec V;
do
{
V = theAdaptor->DN(theU, ++anIndex);
}
while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt P1, P2;
theAdaptor->D0(Min(theU, u), P1);
theAdaptor->D0(Max(theU, u), P2);
gp_Vec V1(P1, P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theAdaptor->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -38,8 +38,7 @@ uses
Shape from GeomAbs,
Curve from GeomAdaptor,
HCurve from Adaptor3d,
HSurface from Adaptor3d,
Cache from BSplSLib
HSurface from Adaptor3d
raises
NoSuchObject from Standard,
@@ -387,12 +386,6 @@ is
TolV : Real = 0.0)
is private;
RebuildCache(me; theU, theV : Real)
---Purpose: Rebuilds B-spline cache
-- \param theU first parameter to identify the span for caching
-- \param theV second parameter to identify the span for caching
is static private;
fields
mySurface : Surface from Geom;
@@ -402,6 +395,5 @@ fields
myVFirst : Real from Standard;
myVLast : Real from Standard;
myTolU, myTolV : Real from Standard;
mySurfaceCache : Cache from BSplSLib;
end Surface;

View File

@@ -51,7 +51,6 @@
#include <gp_Lin.hxx>
#include <gp_Trsf.hxx>
#include <BSplCLib.hxx>
#include <BSplSLib_Cache.hxx>
#include <Precision.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NullObject.hxx>
@@ -132,7 +131,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_BezierSurface;
else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(),
UFirst,ULast,VFirst,VLast);
UFirst,ULast,VFirst,VLast);
}
else if ( TheType == STANDARD_TYPE(Geom_Plane))
mySurfaceType = GeomAbs_Plane;
@@ -150,12 +149,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_SurfaceOfExtrusion;
else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
mySurfaceType = GeomAbs_BSplineSurface;
myBspl = *((Handle(Geom_BSplineSurface)*)&mySurface);
// Create cache for B-spline
mySurfaceCache = new BSplSLib_Cache(
myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
myBspl->Poles(), myBspl->Weights());
myBspl = *((Handle(Geom_BSplineSurface)*)&S);
}
else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
mySurfaceType = GeomAbs_OffsetSurface;
@@ -605,19 +599,6 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
return mySurface->VPeriod();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
const Standard_Real theV) const
{
mySurfaceCache->BuildCache(theU, theV,
myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@@ -626,15 +607,6 @@ void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
const Standard_Real V) const
{
if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
gp_Pnt P;
mySurfaceCache->D0(U, V, P);
return P;
}
return mySurface->Value(U,V);
}
@@ -646,14 +618,6 @@ gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
void GeomAdaptor_Surface::D0(const Standard_Real U,
const Standard_Real V, gp_Pnt& P) const
{
if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D0(U, V, P);
return;
}
mySurface->D0(U,V,P);
}
@@ -665,11 +629,11 @@ void GeomAdaptor_Surface::D0(const Standard_Real U,
void GeomAdaptor_Surface::D1(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V ) const
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V ) const
{
Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
@@ -677,42 +641,39 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType) {
case GeomAbs_BSplineSurface:
if ((USide != 0 || VSide != 0) &&
IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
else if (!mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D1(U, V, P, D1U, D1V);
case GeomAbs_BSplineSurface:
{
if((USide==0)&&(VSide==0)){
myBspl->D1(u,v,P,D1U,D1V);
}
else {
if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
myBspl->LocalD1 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V);
else myBspl->D1(u,v,P,D1U,D1V);
}
break;
}
else
myBspl->D1(u, v, P, D1U, D1V);
break;
case GeomAbs_SurfaceOfExtrusion:
if (USide==0)
myExtSurf->D1(u, v, P, D1U, D1V);
else
myExtSurf->LocalD1(u, v, USide, P, D1U, D1V);
break;
case GeomAbs_SurfaceOfRevolution:
if (VSide==0)
myRevSurf->D1(u, v, P, D1U, D1V);
else
myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V);
break;
case GeomAbs_OffsetSurface:
if (USide==0 && VSide==0)
myOffSurf->D1(u, v, P, D1U, D1V);
else
myOffSurf->LocalD1(u, v, USide, VSide, P, D1U, D1V);
break;
default:
mySurface->D1(u, v, P, D1U, D1V);
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D1(u,v,P,D1U,D1V);
else myExtSurf->LocalD1(u,v,USide,P,D1U,D1V);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D1 (u, v, P,D1U,D1V );
else myRevSurf->LocalD1 (u, v, VSide, P,D1U,D1V );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D1 (u, v,P,D1U,D1V );
else myOffSurf->LocalD1 (u, v, USide, VSide ,P,D1U,D1V );
break;
}
default :
mySurface->D1(u,v,P,D1U,D1V);
}
}
@@ -722,56 +683,50 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
//=======================================================================
void GeomAdaptor_Surface::D2(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
const Standard_Real V, gp_Pnt& P,
gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U,
gp_Vec& D2V, gp_Vec& D2UV) const
{
Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType) {
case GeomAbs_BSplineSurface:
if((USide != 0 || VSide != 0) &&
IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
else if (!mySurfaceCache.IsNull())
switch(mySurfaceType)
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
case GeomAbs_BSplineSurface:
if((USide==0)&&(VSide==0)) myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else{
if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
myBspl->LocalD2 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V,D2U,D2V,D2UV);
else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
}
break;
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
break;
}
default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;}
}
else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
break;
}
default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;}
}
}

View File

@@ -958,19 +958,13 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
BS->EndPoint().XYZ().SquareModulus());
Standard_Real eps = Epsilon(aDist);
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
!BS->IsClosed() && !BS->IsPeriodic())
{
// Avoid creating B-splines containing two coincident poles only
if (mbspc.Degree() == 1 && nbpoles == 2)
continue;
if (!BS->IsClosed() && !BS->IsPeriodic())
{
//force Closed()
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
BS->SetPole(1, aPm);
BS->SetPole(BS->NbPoles(), aPm);
}
//force Closed()
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
BS->SetPole(1, aPm);
BS->SetPole(BS->NbPoles(), aPm);
}
sline.Append(BS);

View File

@@ -1705,8 +1705,6 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface,
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
if (Abs(ww - 1.0) < EpsW)
ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
@@ -1727,8 +1725,6 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface,
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
if (Abs(ww - 1.0) < EpsW)
ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}

View File

@@ -65,5 +65,3 @@ Graphic3d_Camera.cxx
Graphic3d_Camera.hxx
Graphic3d_RenderingParams.hxx
Graphic3d_NMapOfTransient.hxx
Graphic3d_BSDF.hxx
Graphic3d_BSDF.cxx

View File

@@ -362,8 +362,6 @@ is
imported BndBox4d;
imported BufferType;
imported BSDF;
imported CBitFields20;
---Category: Imported types

View File

@@ -1,159 +0,0 @@
// Created on: 2015-01-19
// Created by: Denis BOGOLEPOV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Graphic3d_BSDF.hxx>
#include <algorithm>
// =======================================================================
// function : Serialize
// purpose :
// =======================================================================
Graphic3d_Vec4 Graphic3d_Fresnel::Serialize() const
{
Graphic3d_Vec4 aData = Graphic3d_Vec4 (myFresnelData, 0.f);
if (myFresnelType != Graphic3d_FM_SCHLICK)
{
aData.x() = -static_cast<Standard_ShortReal> (myFresnelType);
}
return aData;
}
// =======================================================================
// function : fresnelNormal
// purpose :
// =======================================================================
inline Standard_ShortReal fresnelNormal (Standard_ShortReal theN,
Standard_ShortReal theK)
{
return ((theN - 1.f) * (theN - 1.f) + theK * theK) /
((theN + 1.f) * (theN + 1.f) + theK * theK);
}
// =======================================================================
// function : CreateConductor
// purpose :
// =======================================================================
Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theRefractionIndex,
const Graphic3d_Vec3& theAbsorptionIndex)
{
return Graphic3d_Fresnel (Graphic3d_FM_SCHLICK,
Graphic3d_Vec3 (fresnelNormal (theRefractionIndex.x(), theAbsorptionIndex.x()),
fresnelNormal (theRefractionIndex.y(), theAbsorptionIndex.y()),
fresnelNormal (theRefractionIndex.z(), theAbsorptionIndex.z())));
}
// =======================================================================
// function : Normalize
// purpose :
// =======================================================================
void Graphic3d_BSDF::Normalize()
{
Standard_ShortReal aMax = std::max (Kd.x() + Ks.x() + Kr.x() + Kt.x(),
std::max (Kd.y() + Ks.y() + Kr.y() + Kt.y(),
Kd.z() + Ks.z() + Kr.z() + Kt.z()));
if (aMax > 1.f)
{
Kd /= aMax;
Ks /= aMax;
Kr /= aMax;
Ks /= aMax;
}
}
// =======================================================================
// function : CreateDiffuse
// purpose :
// =======================================================================
Graphic3d_BSDF Graphic3d_BSDF::CreateDiffuse (const Graphic3d_Vec3& theWeight)
{
Graphic3d_BSDF aBSDF;
aBSDF.Kd = theWeight;
return aBSDF;
}
// =======================================================================
// function : CreateMetallic
// purpose :
// =======================================================================
Graphic3d_BSDF Graphic3d_BSDF::CreateMetallic (const Graphic3d_Vec3& theWeight,
const Graphic3d_Fresnel& theFresnel,
const Standard_ShortReal theRoughness)
{
Graphic3d_BSDF aBSDF;
aBSDF.Roughness = theRoughness;
// Selecting between specular and glossy
// BRDF depending on the given roughness
if (aBSDF.Roughness > 0.f)
{
aBSDF.Ks = theWeight;
}
else
{
aBSDF.Kr = theWeight;
}
aBSDF.Fresnel = theFresnel;
return aBSDF;
}
// =======================================================================
// function : CreateTransparent
// purpose :
// =======================================================================
Graphic3d_BSDF Graphic3d_BSDF::CreateTransparent (const Graphic3d_Vec3& theWeight,
const Graphic3d_Vec3& theAbsorptionColor,
const Standard_ShortReal theAbsorptionCoeff)
{
Graphic3d_BSDF aBSDF;
aBSDF.Kt = theWeight;
aBSDF.AbsorptionColor = theAbsorptionColor;
aBSDF.AbsorptionCoeff = theAbsorptionCoeff;
aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (0.f);
return aBSDF;
}
// =======================================================================
// function : CreateGlass
// purpose :
// =======================================================================
Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
const Graphic3d_Vec3& theAbsorptionColor,
const Standard_ShortReal theAbsorptionCoeff,
const Standard_ShortReal theRefractionIndex)
{
Graphic3d_BSDF aBSDF;
aBSDF.Kt = theWeight;
aBSDF.AbsorptionColor = theAbsorptionColor;
aBSDF.AbsorptionCoeff = theAbsorptionCoeff;
aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (theRefractionIndex);
return aBSDF;
}

Some files were not shown because too many files have changed in this diff Show More