mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
53 Commits
CR29003_2
...
CR0_720_Fi
Author | SHA1 | Date | |
---|---|---|---|
|
2ab2295cec | ||
|
84dd587638 | ||
|
28c0c6b155 | ||
|
47b0f294be | ||
|
7d6be4672b | ||
|
b453701e1f | ||
|
c23d6ec61f | ||
|
b05ff75a60 | ||
|
e49dc1e054 | ||
|
abca9f3eb8 | ||
|
68556f75f9 | ||
|
3d607bc062 | ||
|
365585ddfb | ||
|
c89ab82e4c | ||
|
cc964ef4d3 | ||
|
cb127824b2 | ||
|
fbebf6078c | ||
|
762fa70875 | ||
|
4dd6fb9a80 | ||
|
70608ec03d | ||
|
0842e31d95 | ||
|
51204152b9 | ||
|
d517575214 | ||
|
99d9eb3933 | ||
|
a3430df1d4 | ||
|
9f9ac0fb5a | ||
|
e0fd0b8797 | ||
|
09aae06737 | ||
|
eea07c2f60 | ||
|
9cee51b43b | ||
|
760a94d050 | ||
|
a8375ceaf0 | ||
|
55374b512e | ||
|
52a5d7a61d | ||
|
77676f1b6d | ||
|
515991ffef | ||
|
3d5d9d2b5e | ||
|
51e75dba6c | ||
|
b008680dc0 | ||
|
2b5ced28c3 | ||
|
1c4b27600f | ||
|
214171ff60 | ||
|
22f9125e1e | ||
|
1a196a871d | ||
|
5eba99e74b | ||
|
1560ac5528 | ||
|
4b46072ae9 | ||
|
eed77ff55c | ||
|
118e720920 | ||
|
80f77ed256 | ||
|
8f87d4a954 | ||
|
eeccb2515d | ||
|
b1ee6d0e4b |
@@ -79,7 +79,7 @@ if (WIN32)
|
||||
set (CSF_OpenGlLibs "opengl32.lib")
|
||||
endif()
|
||||
|
||||
else()
|
||||
else()
|
||||
|
||||
if (APPLE)
|
||||
set (CSF_objc "objc")
|
||||
@@ -112,5 +112,6 @@ if (WIN32)
|
||||
set (CSF_OpenGlLibs "GL")
|
||||
set (CSF_XwLibs "X11 Xext Xmu Xi")
|
||||
set (CSF_dl "dl")
|
||||
set (CSF_fontconfig "fontconfig")
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -1375,6 +1375,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
|
||||
set aLibsMap(CSF_TclTkLibs) ""
|
||||
set aLibsMap(CSF_QT) "QtCore QtGui"
|
||||
} else {
|
||||
set aLibsMap(CSF_fontconfig) "fontconfig"
|
||||
if { "$theOS" == "qnx" } {
|
||||
# CSF_ThreadLibs - pthread API is part of libc on QNX
|
||||
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
||||
|
2562
data/occ/hammer.brep
2562
data/occ/hammer.brep
File diff suppressed because one or more lines are too long
@@ -192,11 +192,7 @@ Use prefix <i>bug</i> followed by Mantis issue ID and, if necessary, additional
|
||||
* If the test case reports error due to an existing problem and the fix is not available, add @ref testmanual_3_6 "TODO" statement for each error to mark it as a known problem. The TODO statements must be specific so as to match the actually generated messages but not all similar errors.
|
||||
* To check expected output which should be obtained as the test result, add @ref testmanual_3_7 "REQUIRED" statement for each line of output to mark it as required.
|
||||
* If the test case produces error messages (contained in parse.rules), which are expected in that test and should not be considered as its failure (e.g. test for *checkshape* command), add REQUIRED statement for each error to mark it as required output.
|
||||
4. To check whether the data files needed for the test are already present in the database, use DRAW command *testfile* (see below).
|
||||
If the data file is already present, use it for new test instead of adding a duplicate.
|
||||
If the data file(s) are not yet present in the test database, put them to some folder and add it to the environment variable *CSF_TestDataPath* to be found by the test system.
|
||||
Information on where the data files can be accessed by OCC team for putting to official database should be provided in comment to Mantis issue, clearly indicating how names of the files used by the test script match the actual names of the files.
|
||||
The simplest way is to attach the data files to the Mantis issue, with the same names as used by the test script.
|
||||
4. If the test uses data file(s) that are not yet present in the test database, it is possible to put them to (sub)directory pointed out by *CSF_TestDataPath* variable for running test. The files should be attached to the Mantis issue corresponding to the tested modification.
|
||||
5. Check that the test case runs as expected (test for fix: OK with the fix, FAILED without the fix; test for existing problem: BAD), and integrate it to the Git branch created for the issue.
|
||||
|
||||
Example:
|
||||
@@ -222,33 +218,6 @@ fixshape result a 0.01 0.01
|
||||
checkshape result
|
||||
~~~~~
|
||||
|
||||
DRAW command testfile should be used to check the data files being used by the test for possible duplication of content or names.
|
||||
The command accepts list of paths to files being checked as single argument, and will give conclusion on each of the files, for instance:
|
||||
|
||||
~~~~~
|
||||
Draw[1]> testfile [glob /my/data/path/bug12345*]
|
||||
Collecting info on test data files repository...
|
||||
Checking new file(s)...
|
||||
|
||||
* /my/data/path/bug12345.brep: duplicate
|
||||
already present under name bug28773_1.brep
|
||||
--> //server/occt_tests_data/public/brep/bug28773_1.brep
|
||||
|
||||
* /my/data/path/cadso.brep: new file
|
||||
Warning: DOS encoding detected, consider converting to
|
||||
UNIX unless DOS line ends are needed for the test
|
||||
Warning: shape contains triangulation (946 triangles),
|
||||
consider removing them unless they are needed for the test!
|
||||
BREP size=201 KiB, nbfaces=33, nbedges=94 -> private
|
||||
|
||||
* /my/data/path/case_8_wire3.brep: already present
|
||||
--> //server/occt_tests_data/public/brep/case_8_wire3.brep
|
||||
|
||||
* /my/data/path/case_8_wire4.brep: error
|
||||
name is already used by existing file
|
||||
--> //server/occt_tests_data/public/brep/case_8_wire4.brep
|
||||
~~~~~
|
||||
|
||||
@section testmanual_2 Organization of Test Scripts
|
||||
|
||||
@subsection testmanual_2_1 General Layout
|
||||
|
@@ -1437,3 +1437,10 @@ The Error/Warning reporting system of the algorithms in Boolean Component (in al
|
||||
The methods returning the status of errors and warnings of the algorithms (ErrorStatus() and WarningStatus()) have been removed.
|
||||
Instead use methods HasErrors() and HasWarnings() to check for presence of errors and warnings, respectively.
|
||||
The full list of errors and warnings, with associated data such as problematic sub-shapes, can be obtained by method GetReport().
|
||||
|
||||
@section upgrade_occt730 Upgrade to OCCT 7.3.0
|
||||
|
||||
@subsection upgrade_730_BRepAdaptor_CompCurve Changes in BRepAdaptor_CompCurve
|
||||
|
||||
The method BRepAdaptor_CompCurve::SetPeriodic has been eliminated.
|
||||
Since new version, the method BRepAdaptor_CompCurve::IsPeriodic() will always return FALSE. Earlier, it could return TRUE in case if the wire contained only one edge based on periodic curve.
|
||||
|
@@ -3,24 +3,19 @@
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "custom.sh" ]; then
|
||||
source "custom.sh" $*;
|
||||
source "custom.sh";
|
||||
fi
|
||||
|
||||
if [ -e "${aSamplePath}/../../../env.sh" ]; then
|
||||
source "${aSamplePath}/../../../env.sh" $*;
|
||||
source "${aSamplePath}/../../../env.sh";
|
||||
fi
|
||||
|
||||
if [ "${QTDIR}" != "" ]; then
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
else
|
||||
aQMakePath=`which qmake`
|
||||
echo "Environment variable \"QTDIR\" not defined.. Define it in \"custom.sh\" script."
|
||||
if [ -x "$aQMakePath" ]; then
|
||||
echo "qmake from PATH will be used instead."
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
if test "${QTDIR}" == ""; then
|
||||
echo "Environment variable \"QTDIR\" not defined. Define it in \"custom.sh\" script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host=`uname -s`
|
||||
export STATION=$host
|
||||
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
|
@@ -1,14 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
qmake FuncDemo.pro
|
||||
if [ "$(uname -s)" != "Darwin" ] || [ "$MACOSX_USE_GLX" == "true" ]; then
|
||||
aNbJobs="$(getconf _NPROCESSORS_ONLN)"
|
||||
if [ "${CASDEB}" == "d" ]; then
|
||||
make -j $aNbJobs debug
|
||||
make debug
|
||||
else
|
||||
make -j $aNbJobs release
|
||||
make release
|
||||
fi
|
||||
fi
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
|
||||
aSystem=`uname -s`
|
||||
|
@@ -3,25 +3,20 @@
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "custom.sh" ]; then
|
||||
source "custom.sh" $*;
|
||||
source "custom.sh";
|
||||
fi
|
||||
|
||||
if [ -e "${aSamplePath}/../../../env.sh" ]; then
|
||||
source "${aSamplePath}/../../../env.sh" $*;
|
||||
source "${aSamplePath}/../../../env.sh";
|
||||
fi
|
||||
|
||||
if [ "${QTDIR}" != "" ]; then
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
else
|
||||
aQMakePath=`which qmake`
|
||||
echo "Environment variable \"QTDIR\" not defined.. Define it in \"custom.sh\" script."
|
||||
if [ -x "$aQMakePath" ]; then
|
||||
echo "qmake from PATH will be used instead."
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
if test "${QTDIR}" == ""; then
|
||||
echo "Environment variable \"QTDIR\" not defined. Define it in \"custom.sh\" script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host=`uname -s`
|
||||
export STATION=$host
|
||||
export RES_DIR=${aSamplePath}/${STATION}/res
|
||||
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
|
@@ -1,14 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
qmake IESample.pro
|
||||
if [ "$(uname -s)" != "Darwin" ] || [ "$MACOSX_USE_GLX" == "true" ]; then
|
||||
aNbJobs="$(getconf _NPROCESSORS_ONLN)"
|
||||
if [ "${CASDEB}" == "d" ]; then
|
||||
make -j $aNbJobs debug
|
||||
make debug
|
||||
else
|
||||
make -j $aNbJobs release
|
||||
make release
|
||||
fi
|
||||
fi
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
|
||||
aSystem=`uname -s`
|
||||
|
@@ -3,25 +3,20 @@
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "custom.sh" ]; then
|
||||
source "custom.sh" $*;
|
||||
source "custom.sh";
|
||||
fi
|
||||
|
||||
if [ -e "${aSamplePath}/../../../env.sh" ]; then
|
||||
source "${aSamplePath}/../../../env.sh" $*;
|
||||
source "${aSamplePath}/../../../env.sh";
|
||||
fi
|
||||
|
||||
if [ "${QTDIR}" != "" ]; then
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
else
|
||||
aQMakePath=`which qmake`
|
||||
echo "Environment variable \"QTDIR\" not defined.. Define it in \"custom.sh\" script."
|
||||
if [ -x "$aQMakePath" ]; then
|
||||
echo "qmake from PATH will be used instead."
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
if test "${QTDIR}" == ""; then
|
||||
echo "Environment variable \"QTDIR\" not defined. Define it in \"custom.sh\" script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host=`uname -s`
|
||||
export STATION=$host
|
||||
export RES_DIR=${aSamplePath}/${STATION}/res
|
||||
|
||||
export PATH=${QTDIR}/bin:${PATH}
|
||||
|
@@ -1,14 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
qmake Tutorial.pro
|
||||
if [ "$(uname -s)" != "Darwin" ] || [ "$MACOSX_USE_GLX" == "true" ]; then
|
||||
aNbJobs="$(getconf _NPROCESSORS_ONLN)"
|
||||
if [ "${CASDEB}" == "d" ]; then
|
||||
make -j $aNbJobs debug
|
||||
make debug
|
||||
else
|
||||
make -j $aNbJobs release
|
||||
make release
|
||||
fi
|
||||
fi
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
export aSamplePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh" $*; fi
|
||||
if [ -e "${aSamplePath}/env.sh" ]; then source "${aSamplePath}/env.sh"; fi
|
||||
cd $aSamplePath
|
||||
|
||||
aSystem=`uname -s`
|
||||
|
@@ -9,6 +9,8 @@ pload VISUALIZATION
|
||||
|
||||
vinit View1 w=1024 h=1024
|
||||
vclear
|
||||
vdefaults -autoTriang 0
|
||||
vrenderparams -stats basic
|
||||
|
||||
# parameter NB defines number of spheres by each coordinate
|
||||
set NB 10
|
||||
@@ -23,11 +25,12 @@ for {set i 0} {$i < $NB} {incr i} {
|
||||
}
|
||||
}
|
||||
}
|
||||
eval compound $slist c
|
||||
incmesh c 0.006
|
||||
|
||||
puts "Measuring FPS of display of spheres as separate objects..."
|
||||
vaxo
|
||||
vsetdispmode 1
|
||||
eval vdisplay $slist
|
||||
eval vdisplay -dispMode 1 $slist
|
||||
vfit
|
||||
|
||||
# measure FPS
|
||||
@@ -35,16 +38,14 @@ puts [set fps_separate [vfps]]
|
||||
vclear
|
||||
|
||||
puts "Measuring FPS of display of spheres as single object..."
|
||||
eval compound $slist c
|
||||
vdisplay c
|
||||
vdisplay -dispMode 1 c
|
||||
|
||||
# measure FPS
|
||||
puts [set fps_compound [vfps]]
|
||||
vclear
|
||||
|
||||
# redisplay individual spheres, trying to avoid unnecessary internal updates
|
||||
#vfrustumculling 0 ;# try to disable updates of frustum culling structures
|
||||
eval vdisplay -mutable $slist
|
||||
eval vdisplay -dispMode 1 $slist
|
||||
|
||||
# auxiliary procedure to make random update of variable
|
||||
proc upd {theValueName theDeltaName theTime theToRand} {
|
||||
@@ -69,8 +70,10 @@ proc animateSpheres {{theDuration 10.0}} {
|
||||
for {set i 0} {$i < $::NB} {incr i $nb} {
|
||||
for {set j 0} {$j < $::NB} {incr j $nb} {
|
||||
for {set k 0} {$k < $::NB} {incr k $nb} {
|
||||
# mark animated spheres mutable for faster updates
|
||||
uplevel #0 vdisplay -dispMode 1 -mutable s$i$j$k
|
||||
# vaspects -noupdate s$i$j$k -setcolor red -setmaterial plastic
|
||||
vaspects -noupdate s$i$j$k -setcolor red
|
||||
uplevel #0 vaspects -noupdate s$i$j$k -setcolor red
|
||||
set x$i$j$k 0.0
|
||||
set y$i$j$k 0.0
|
||||
set z$i$j$k 0.0
|
||||
@@ -142,4 +145,4 @@ puts "Animation FPS: $fps_animation"
|
||||
puts ""
|
||||
puts "Scene contains [lindex [trinfo c] 3] triangles"
|
||||
puts ""
|
||||
puts "Print 'animateSpheres 10.0' to restart animation"
|
||||
puts "Print 'animateSpheres 10.0' to restart animation"
|
||||
|
@@ -783,6 +783,7 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
BRepAdaptor_Surface surf1( aFace );
|
||||
Handle( Adaptor3d_HSurface ) surf2;
|
||||
Standard_Boolean isOffset = Standard_False;
|
||||
Offset = 0.0;
|
||||
|
||||
if (surf1.GetType() == GeomAbs_OffsetSurface)
|
||||
{
|
||||
@@ -801,7 +802,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aPlane = surf2->Plane();
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
|
||||
@@ -817,7 +817,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
|
||||
aPlane = thePlane;
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
}
|
||||
@@ -826,7 +825,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
if (Result == Standard_False)
|
||||
{
|
||||
@@ -839,7 +837,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
TheType == STANDARD_TYPE(Geom_ToroidalSurface))
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -899,20 +896,18 @@ gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
|
||||
//function : InitFaceLength
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS::InitFaceLength (const TopoDS_Face& aFace,
|
||||
gp_Pln & aPlane,
|
||||
Handle(Geom_Surface) & aSurface,
|
||||
AIS_KindOfSurface & aSurfaceType,
|
||||
Standard_Real & anOffset)
|
||||
void AIS::InitFaceLength (const TopoDS_Face& theFace,
|
||||
gp_Pln& thePlane,
|
||||
Handle(Geom_Surface)& theSurface,
|
||||
AIS_KindOfSurface& theSurfaceType,
|
||||
Standard_Real& theOffset)
|
||||
{
|
||||
AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
|
||||
|
||||
if (Abs( anOffset ) > Precision::Confusion())
|
||||
{
|
||||
aSurface = new Geom_OffsetSurface( aSurface, anOffset );
|
||||
anOffset = 0.0e0;
|
||||
}
|
||||
|
||||
if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
|
||||
&& Abs (theOffset) > Precision::Confusion())
|
||||
{
|
||||
theSurface = new Geom_OffsetSurface (theSurface, theOffset);
|
||||
theOffset = 0.0e0;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -335,31 +335,31 @@ TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidt
|
||||
if (myDrawer->DimensionAspect()->IsText3d())
|
||||
{
|
||||
// text width produced by BRepFont
|
||||
Font_BRepFont aFont (aTextAspect->Aspect()->Font().ToCString(),
|
||||
aTextAspect->Aspect()->GetTextFontAspect(),
|
||||
aTextAspect->Height());
|
||||
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
Font_BRepFont aFont;
|
||||
if (aFont.FindAndInit (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aTextAspect->Height(), Font_StrictLevel_Any))
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
Standard_Utf32Char aNextChar = *(++anIter);
|
||||
theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
Standard_Utf32Char aNextChar = *(++anIter);
|
||||
theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Text width for 1:1 scale 2D case
|
||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||
aFont->Init (aTextAspect->Aspect()->Font().ToCString(),
|
||||
aTextAspect->Aspect()->GetTextFontAspect(),
|
||||
(const unsigned int)aTextAspect->Height(),
|
||||
THE_2D_TEXT_RESOLUTION);
|
||||
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
Font_FTFontParams aFontParams;
|
||||
aFontParams.PointSize = (unsigned int )aTextAspect->Height();
|
||||
aFontParams.Resolution = THE_2D_TEXT_RESOLUTION;
|
||||
if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aFontParams, Font_StrictLevel_Any))
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
Standard_Utf32Char aNextChar = *(++anIter);
|
||||
theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
Standard_Utf32Char aNextChar = *(++anIter);
|
||||
theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1386,14 +1386,7 @@ protected: //! @name internal methods
|
||||
if (myLastinMain.IsNull())
|
||||
return;
|
||||
|
||||
if (myLastinMain->IsAutoHilight())
|
||||
{
|
||||
myMainPM->ClearImmediateDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
myLastinMain->Selectable()->ClearDynamicHighlight (myMainPM);
|
||||
}
|
||||
myLastinMain->Selectable()->ClearDynamicHighlight (myMainPM);
|
||||
}
|
||||
|
||||
protected: //! @name internal fields
|
||||
|
@@ -1005,7 +1005,8 @@ void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
|
||||
gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aSystem, gp_Ax3());
|
||||
aTool.FillArray (myArray, myTriangulation, aTrsf);
|
||||
myArray = aTool.CreateTriangulation (aTrsf);
|
||||
myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1024,7 +1025,8 @@ void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
|
||||
Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
|
||||
aTool.FillArray (myArray, myTriangulation, aTrsf);
|
||||
myArray = aTool.CreateTriangulation (aTrsf);
|
||||
myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1060,24 +1062,24 @@ void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_Shor
|
||||
addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
|
||||
|
||||
// Front
|
||||
addTriangle (2, aV3, aV4, aV5, aFront);
|
||||
addTriangle (3, aV3, aV5, aTopRight, aFront);
|
||||
addTriangle (2, aV3, aV5, aV4, -aFront);
|
||||
addTriangle (3, aV3, aTopRight, aV5, -aFront);
|
||||
|
||||
// Back
|
||||
addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
|
||||
addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
|
||||
addTriangle (4, aBottomLeft, aV7, aV2, aFront);
|
||||
addTriangle (5, aBottomLeft, aV6, aV7, aFront);
|
||||
|
||||
// aTop
|
||||
addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
|
||||
addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
|
||||
|
||||
//Left
|
||||
addTriangle (8, aV6, aV5, aV4, -aRight);
|
||||
addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
|
||||
// Left
|
||||
addTriangle (8, aV6, aV4, aV5, aRight);
|
||||
addTriangle (9, aBottomLeft, aV4, aV6, aRight);
|
||||
|
||||
// Right
|
||||
addTriangle (10, aV3, aTopRight, aV7, aRight);
|
||||
addTriangle (11, aV3, aV7, aV2, aRight);
|
||||
addTriangle (10, aV3, aV7, aTopRight, -aRight);
|
||||
addTriangle (11, aV3, aV2, aV7, -aRight);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1148,6 +1150,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
|
||||
anArrowLength,
|
||||
myFacettesNumber);
|
||||
myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
|
||||
myTranslatorGroup->SetClosed (true);
|
||||
myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
|
||||
myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
|
||||
|
||||
@@ -1169,6 +1172,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
|
||||
myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
|
||||
|
||||
myScalerGroup = Prs3d_Root::NewGroup (thePrs);
|
||||
myScalerGroup->SetClosed (true);
|
||||
myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
|
||||
myScalerGroup->AddPrimitiveArray (myCube.Array());
|
||||
|
||||
|
@@ -261,14 +261,14 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
|
||||
if (myHasFlipping)
|
||||
{
|
||||
// Get width and height of text
|
||||
Font_FTFont aFont;
|
||||
unsigned int aResolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
|
||||
if (aFont.Init (anAsp->Aspect()->Font().ToCString(),
|
||||
anAsp->Aspect()->GetTextFontAspect(), (unsigned int)anAsp->Height(), aResolution))
|
||||
Font_FTFontParams aFontParams;
|
||||
aFontParams.PointSize = (unsigned int )anAsp->Height();
|
||||
aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
|
||||
if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(), anAsp->Aspect()->GetTextFontAspect(), aFontParams))
|
||||
{
|
||||
isInit = Standard_True;
|
||||
const NCollection_String aText (myText.ToExtString());
|
||||
Font_Rect aBndBox = aFont.BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
|
||||
Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
|
||||
Standard_Real aWidth = Abs (aBndBox.Width());
|
||||
Standard_Real aHeight = Abs (aBndBox.Height());
|
||||
gp_Pnt aCenterOfLabel = aPosition;
|
||||
|
@@ -458,7 +458,7 @@ GeomAbs_CurveType Adaptor2d_OffsetCurve::GetType() const {
|
||||
return GeomAbs_Circle;
|
||||
|
||||
default:
|
||||
return GeomAbs_OtherCurve;
|
||||
return GeomAbs_OffsetCurve;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -650,3 +650,27 @@ Handle(Geom2d_BSplineCurve) Adaptor2d_OffsetCurve::BSpline() const
|
||||
"Adaptor2d_OffsetCurve::BSpline() - wrong curve type");
|
||||
return myCurve->BSpline();
|
||||
}
|
||||
|
||||
static Standard_Integer nbPoints(const Handle(Adaptor2d_HCurve2d)& theCurve)
|
||||
{
|
||||
|
||||
Standard_Integer nbs = 20;
|
||||
|
||||
if (theCurve->GetType() == GeomAbs_BezierCurve)
|
||||
{
|
||||
nbs = Max(nbs, 3 + theCurve->NbPoles());
|
||||
}
|
||||
else if (theCurve->GetType() == GeomAbs_BSplineCurve) {
|
||||
nbs = Max(nbs, theCurve->NbKnots() * theCurve->Degree());
|
||||
}
|
||||
|
||||
if (nbs > 300)
|
||||
nbs = 300;
|
||||
return nbs;
|
||||
|
||||
}
|
||||
|
||||
Standard_Integer Adaptor2d_OffsetCurve::NbSamples() const
|
||||
{
|
||||
return nbPoints(myCurve);
|
||||
}
|
||||
|
@@ -174,6 +174,8 @@ public:
|
||||
|
||||
Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT Standard_Integer NbSamples() const Standard_OVERRIDE;;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -67,3 +67,6 @@ Warning: Removal of internal boundaries among Faces has failed
|
||||
|
||||
.BOPAlgo_AlertRemovalOfIBForEdgesFailed
|
||||
Warning: Removal of internal boundaries among Edges has failed
|
||||
|
||||
.BOPAlgo_AlertSolidBuilderUnusedFaces
|
||||
Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
|
||||
|
@@ -78,4 +78,7 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShellSplitterFailed)
|
||||
//! Some edges are too small and have no valid range
|
||||
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge)
|
||||
|
||||
//! Some of the faces passed to the Solid Builder algorithm have not been classified
|
||||
//! and not used for solids creation
|
||||
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
|
||||
#endif // _BOPAlgo_Alerts_HeaderFile
|
||||
|
@@ -69,4 +69,7 @@ static const char BOPAlgo_BOPAlgo_msg[] =
|
||||
"Warning: Removal of internal boundaries among Faces has failed\n"
|
||||
"\n"
|
||||
".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n"
|
||||
"Warning: Removal of internal boundaries among Edges has failed\n";
|
||||
"Warning: Removal of internal boundaries among Edges has failed\n"
|
||||
"\n"
|
||||
".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
|
||||
"Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n";
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <BOPAlgo_BuilderSolid.hxx>
|
||||
#include <BOPAlgo_ShellSplitter.hxx>
|
||||
#include <BOPAlgo_Alerts.hxx>
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_DataMapOfShapeShape.hxx>
|
||||
@@ -127,127 +128,7 @@ typedef NCollection_DataMap
|
||||
//
|
||||
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
|
||||
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
|
||||
//
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FacePnt
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FacePnt {
|
||||
public:
|
||||
BOPAlgo_FacePnt() {
|
||||
}
|
||||
//
|
||||
virtual ~BOPAlgo_FacePnt() {
|
||||
}
|
||||
//
|
||||
void SetFace(const TopoDS_Face& aFace) {
|
||||
myFace=aFace;
|
||||
}
|
||||
//
|
||||
const TopoDS_Face& Face()const {
|
||||
return myFace;
|
||||
}
|
||||
//
|
||||
void SetPnt(const gp_Pnt& aPnt) {
|
||||
myPnt=aPnt;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& Pnt()const {
|
||||
return myPnt;
|
||||
}
|
||||
//
|
||||
protected:
|
||||
gp_Pnt myPnt;
|
||||
TopoDS_Face myFace;
|
||||
};
|
||||
//
|
||||
typedef BOPCol_NCVector
|
||||
<BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt;
|
||||
//
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FaceSolid
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
BOPAlgo_FaceSolid() :
|
||||
myIsInternalFace(Standard_False) {
|
||||
}
|
||||
//
|
||||
virtual ~BOPAlgo_FaceSolid() {
|
||||
}
|
||||
//
|
||||
void SetFace(const TopoDS_Face& aFace) {
|
||||
myFace=aFace;
|
||||
}
|
||||
//
|
||||
const TopoDS_Face& Face()const {
|
||||
return myFace;
|
||||
}
|
||||
//
|
||||
void SetSolid(const TopoDS_Solid& aSolid) {
|
||||
mySolid=aSolid;
|
||||
}
|
||||
//
|
||||
const TopoDS_Solid& Solid()const {
|
||||
return mySolid;
|
||||
}
|
||||
//
|
||||
void SetPnt(const gp_Pnt& aPnt) {
|
||||
myPnt=aPnt;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& Pnt()const {
|
||||
return myPnt;
|
||||
}
|
||||
void SetContext(const Handle(IntTools_Context)& aContext) {
|
||||
myContext=aContext;
|
||||
}
|
||||
//
|
||||
const Handle(IntTools_Context)& Context()const {
|
||||
return myContext;
|
||||
}
|
||||
//
|
||||
Standard_Boolean IsInternalFace() const {
|
||||
return myIsInternalFace;
|
||||
}
|
||||
//
|
||||
virtual void Perform () {
|
||||
TopAbs_State aState;
|
||||
//
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
//
|
||||
aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid,
|
||||
Precision::Confusion(),
|
||||
myContext);
|
||||
//
|
||||
myIsInternalFace=(aState==TopAbs_IN);
|
||||
}
|
||||
//
|
||||
protected:
|
||||
Standard_Boolean myIsInternalFace;
|
||||
gp_Pnt myPnt;
|
||||
TopoDS_Face myFace;
|
||||
TopoDS_Solid mySolid;
|
||||
Handle(IntTools_Context) myContext;
|
||||
};
|
||||
//=======================================================================
|
||||
typedef BOPCol_NCVector
|
||||
<BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid;
|
||||
//
|
||||
typedef BOPCol_ContextFunctor
|
||||
<BOPAlgo_FaceSolid,
|
||||
BOPAlgo_VectorOfFaceSolid,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPAlgo_FaceSolidFunctor;
|
||||
//
|
||||
typedef BOPCol_ContextCnt
|
||||
<BOPAlgo_FaceSolidFunctor,
|
||||
BOPAlgo_VectorOfFaceSolid,
|
||||
Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
|
||||
//
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
@@ -766,49 +647,29 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
|
||||
return;
|
||||
}
|
||||
//
|
||||
Standard_Boolean bIsInternalFace;
|
||||
Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
|
||||
BRep_Builder aBB;
|
||||
TopoDS_Iterator aIt;
|
||||
TopExp_Explorer aExp;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
BOPCol_IndexedMapOfShape aMFs;
|
||||
BOPCol_ListOfShape aLSI;
|
||||
BOPAlgo_VectorOfFaceSolid aVFS;
|
||||
BOPAlgo_VectorOfFacePnt aVFP;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI;
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller
|
||||
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
//
|
||||
aNbA=myAreas.Extent();
|
||||
Standard_Integer aNbA = myAreas.Extent();
|
||||
//
|
||||
// 1. aVFP
|
||||
// Fill Tree with boxes
|
||||
aItLS.Initialize(myLoopsInternal);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aShell=aItLS.Value();
|
||||
aIt.Initialize(aShell);
|
||||
TopoDS_Iterator aIt(aShell);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
|
||||
//
|
||||
if (!aMFs.Contains(aF)) {
|
||||
if (!aMFs.Contains(aF))
|
||||
{
|
||||
aMFs.Add(aF);
|
||||
//
|
||||
gp_Pnt aP;
|
||||
gp_Pnt2d aP2D;
|
||||
//
|
||||
if (aNbA) {
|
||||
BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
|
||||
}
|
||||
//
|
||||
BOPAlgo_FacePnt& aFP=aVFP.Append1();
|
||||
aFP.SetFace(aF);
|
||||
aFP.SetPnt(aP);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
if (!aNbA) {
|
||||
// 7b. "Rest" faces treatment
|
||||
TopoDS_Solid aSolid;
|
||||
@@ -826,146 +687,81 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
|
||||
return; // =>
|
||||
}//if (!aNbA) {
|
||||
//
|
||||
// 2. Prepare TreeFiller
|
||||
aNbVFP=aVFP.Extent();
|
||||
for(k=0; k<aNbVFP; ++k) {
|
||||
Bnd_Box aBox;
|
||||
//
|
||||
const BOPAlgo_FacePnt& aFP=aVFP(k);
|
||||
const TopoDS_Face& aF=aFP.Face();
|
||||
//
|
||||
BRepBndLib::Add(aF, aBox);
|
||||
aTreeFiller.Add(k, aBox);
|
||||
}
|
||||
//
|
||||
aTreeFiller.Fill();
|
||||
//
|
||||
// 3. Face/Solid candidates: aVFS
|
||||
aItLS.Initialize(myAreas);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
Bnd_Box aBox;
|
||||
//
|
||||
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
|
||||
BRepBndLib::Add(aSolid, aBox);
|
||||
//
|
||||
aMFs.Clear();
|
||||
aExp.Init(aSolid, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
const TopoDS_Shape& aFs=aExp.Current();
|
||||
aMFs.Add(aFs);
|
||||
}
|
||||
//
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(aBox);
|
||||
//
|
||||
aBBTree.Select(aSelector);
|
||||
//
|
||||
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
|
||||
aItLI.Initialize(aLI);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
k=aItLI.Value();
|
||||
const BOPAlgo_FacePnt& aFP=aVFP(k);
|
||||
const TopoDS_Face& aF=aFP.Face();
|
||||
if (aMFs.Contains(aF)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& aP=aFP.Pnt();
|
||||
//
|
||||
BOPAlgo_FaceSolid& aFS=aVFS.Append1();
|
||||
aFS.SetPnt(aP);
|
||||
aFS.SetFace(aF);
|
||||
aFS.SetSolid(aSolid);
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbVFS=aVFS.Extent();
|
||||
if (!aNbVFS) {
|
||||
return;
|
||||
}
|
||||
// 4. Refine candidates
|
||||
//=============================================================
|
||||
BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
|
||||
//=============================================================
|
||||
//
|
||||
// 5. Solid/Faces: aMSLF
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
|
||||
BOPCol_MapOfShape aMFProcessed;
|
||||
//
|
||||
for (k=0; k < aNbVFS; ++k) {
|
||||
const BOPAlgo_FaceSolid& aFS=aVFS(k);
|
||||
//
|
||||
const TopoDS_Solid& aSolid=aFS.Solid();
|
||||
const TopoDS_Face& aF=aFS.Face();
|
||||
//
|
||||
bIsInternalFace=aFS.IsInternalFace();
|
||||
if (!bIsInternalFace) {
|
||||
|
||||
// Prepare list of faces to classify
|
||||
TopTools_ListOfShape aLFaces;
|
||||
Standard_Integer i, aNbF = aMFs.Extent();
|
||||
for (i = 1; i <= aNbF; ++i)
|
||||
aLFaces.Append(aMFs(i));
|
||||
|
||||
// Map of solids with IN faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMSLF;
|
||||
|
||||
// Perform classification
|
||||
BOPAlgo_Tools::ClassifyFaces(aLFaces, myAreas, myRunParallel, myContext, aMSLF);
|
||||
|
||||
// Update Solids by internal Faces
|
||||
|
||||
BOPCol_MapOfShape aMFDone;
|
||||
|
||||
Standard_Integer aNbS = aMSLF.Extent();
|
||||
for (i = 1; i <= aNbS; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aSolid = aMSLF.FindKey(i);
|
||||
TopoDS_Shape *pSolid = (TopoDS_Shape*)&aSolid;
|
||||
|
||||
const TopTools_ListOfShape& aLF = aMSLF(i);
|
||||
if (aLF.IsEmpty())
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (aMSLF.Contains(aSolid)) {
|
||||
BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
|
||||
aLF.Append(aF);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLF;
|
||||
//
|
||||
aLF.Append(aF);
|
||||
aMSLF.Add(aSolid, aLF);
|
||||
}
|
||||
}// for (k=0; k < aNbVE; ++k) {
|
||||
//
|
||||
// 6. Update Solids by internal Faces
|
||||
aNbSLF=aMSLF.Extent();
|
||||
for (k=1; k <= aNbSLF; ++k) {
|
||||
const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
|
||||
TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
|
||||
//
|
||||
const BOPCol_ListOfShape& aLF=aMSLF(k);
|
||||
//
|
||||
aMFs.Clear();
|
||||
|
||||
TopTools_IndexedMapOfShape aMF;
|
||||
aItLS.Initialize(aLF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aF=aItLS.Value();
|
||||
aMFs.Add(aF);
|
||||
aMFProcessed.Add(aF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItLS.Value();
|
||||
aMF.Add(aF);
|
||||
aMFDone.Add(aF);
|
||||
}
|
||||
//
|
||||
aLSI.Clear();
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
MakeInternalShells(aMF, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSI = aItLS.Value();
|
||||
aBB.Add (*pSolid, aSI);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 7. "Rest" faces treatment (if there are)
|
||||
aMFs.Clear();
|
||||
for (k=0; k < aNbVFS; ++k) {
|
||||
const BOPAlgo_FaceSolid& aFS=aVFS(k);
|
||||
//
|
||||
const TopoDS_Face& aF=aFS.Face();
|
||||
if (!aMFProcessed.Contains(aF)) {
|
||||
aMFs.Add(aF);
|
||||
}
|
||||
|
||||
// Find all unclassified faces and warn the user about them.
|
||||
TopTools_IndexedMapOfShape aMFUnUsed;
|
||||
|
||||
for (i = 1; i <= aNbF; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aF = aMFs(i);
|
||||
if (!aMFDone.Contains(aF))
|
||||
aMFUnUsed.Add(aF);
|
||||
}
|
||||
//
|
||||
aNbFI=aMFs.Extent();
|
||||
if (aNbFI) {
|
||||
TopoDS_Solid aSolid;
|
||||
aBB.MakeSolid(aSolid);
|
||||
//
|
||||
|
||||
if (aMFUnUsed.Extent())
|
||||
{
|
||||
aLSI.Clear();
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
|
||||
//TopoDS_Solid aShape;
|
||||
//aBB.MakeSolid (aShape);
|
||||
TopoDS_Compound aShape;
|
||||
aBB.MakeCompound (aShape);
|
||||
|
||||
aItLS.Initialize (aLSI);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
aBB.Add (aSolid, aSI);
|
||||
aBB.Add (aShape, aSI);
|
||||
}
|
||||
myAreas.Append(aSolid);
|
||||
//myAreas.Append (aShape);
|
||||
AddWarning (new BOPAlgo_AlertSolidBuilderUnusedFaces (aShape));
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
|
@@ -19,6 +19,7 @@
|
||||
//
|
||||
#include <Precision.hxx>
|
||||
//
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
//
|
||||
#include <Bnd_Box.hxx>
|
||||
@@ -43,9 +44,13 @@
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
//
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
//
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
#include <BOPCol_MapOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <BOPCol_ListOfShape.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_ListOfInteger.hxx>
|
||||
@@ -131,367 +136,6 @@ class BOPAlgo_ShapeBox {
|
||||
typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
|
||||
//
|
||||
//=======================================================================
|
||||
// class: BOPAlgo_FillIn3DParts
|
||||
//
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_FillIn3DParts
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo {
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
BOPAlgo_FillIn3DParts(){
|
||||
myHasImage=Standard_False;
|
||||
myBBTree=NULL;
|
||||
myVSB=NULL;
|
||||
};
|
||||
//
|
||||
virtual ~BOPAlgo_FillIn3DParts(){
|
||||
};
|
||||
//
|
||||
void SetSolid(const TopoDS_Solid& aS) {
|
||||
mySolid=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Solid& Solid()const {
|
||||
return mySolid;
|
||||
};
|
||||
//
|
||||
void SetDraftSolid(const TopoDS_Solid& aS) {
|
||||
myDraftSolid=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Solid& DraftSolid()const {
|
||||
return myDraftSolid;
|
||||
};
|
||||
//
|
||||
void SetHasImage(const Standard_Boolean bFlag) {
|
||||
myHasImage=bFlag;
|
||||
};
|
||||
//
|
||||
Standard_Boolean HasImage()const {
|
||||
return myHasImage;
|
||||
};
|
||||
//
|
||||
void SetBoxS(const Bnd_Box& aBox) {
|
||||
myBoxS=aBox;
|
||||
};
|
||||
//
|
||||
const Bnd_Box& BoxS()const {
|
||||
return myBoxS;
|
||||
};
|
||||
//
|
||||
void SetLIF(const BOPCol_ListOfShape& aLIF) {
|
||||
myLIF=aLIF;
|
||||
};
|
||||
//
|
||||
const BOPCol_ListOfShape& LIF()const {
|
||||
return myLIF;
|
||||
};
|
||||
//
|
||||
void SetBBTree(const BOPCol_BoxBndTree& aBBTree) {
|
||||
myBBTree=(BOPCol_BoxBndTree*)&aBBTree;
|
||||
};
|
||||
//
|
||||
void SetVSB(const BOPAlgo_VectorOfShapeBox& aVSB) {
|
||||
myVSB=(BOPAlgo_VectorOfShapeBox*)&aVSB;
|
||||
};
|
||||
//
|
||||
//
|
||||
void SetContext(const Handle(IntTools_Context)& aContext) {
|
||||
myContext=aContext;
|
||||
}
|
||||
//
|
||||
const Handle(IntTools_Context)& Context()const {
|
||||
return myContext;
|
||||
}
|
||||
//
|
||||
virtual void Perform();
|
||||
//
|
||||
|
||||
//
|
||||
const BOPCol_ListOfShape& LFIN()const {
|
||||
return myLFIN;
|
||||
};
|
||||
|
||||
protected:
|
||||
void MapEdgesAndFaces
|
||||
(const TopoDS_Shape& ,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& ,
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
|
||||
void MakeConnexityBlock
|
||||
(const BOPCol_ListOfShape& ,
|
||||
const BOPCol_IndexedMapOfShape& ,
|
||||
const BOPCol_MapOfShape& ,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& ,
|
||||
BOPCol_ListOfShape& ,
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
//
|
||||
protected:
|
||||
TopoDS_Solid mySolid;
|
||||
TopoDS_Solid myDraftSolid;
|
||||
Standard_Boolean myHasImage;
|
||||
Bnd_Box myBoxS;
|
||||
BOPCol_ListOfShape myLIF;
|
||||
BOPCol_ListOfShape myLFIN;
|
||||
//
|
||||
BOPCol_BoxBndTree* myBBTree;
|
||||
BOPAlgo_VectorOfShapeBox* myVSB;
|
||||
//
|
||||
TopoDS_Iterator myItF;
|
||||
TopoDS_Iterator myItW;
|
||||
|
||||
Handle(IntTools_Context) myContext;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FillIn3DParts::Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::Perform()
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) aAlr1;
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
//
|
||||
Standard_Integer aNbFP, k, nFP, iIsIN;
|
||||
Standard_Real aTolPC;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
//
|
||||
aAlr1=
|
||||
NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
//
|
||||
BOPCol_ListOfShape aLFP(aAlr1);
|
||||
BOPCol_ListOfShape aLCBF(aAlr1);
|
||||
BOPCol_MapOfShape aMFDone(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aME(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aMF(100, aAlr1);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAlr1);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
|
||||
//
|
||||
aTolPC=Precision::Confusion();
|
||||
myLFIN.Clear();
|
||||
BOPAlgo_VectorOfShapeBox& aVSB=*myVSB;
|
||||
//
|
||||
// 1. aMEF - EF map for myDraftSolid
|
||||
BOPTools::MapShapesAndAncestors(myDraftSolid,
|
||||
TopAbs_EDGE,
|
||||
TopAbs_FACE,
|
||||
aMEF);
|
||||
|
||||
//
|
||||
// 2. Faces from myDraftSolid and its own internal faces => aMF
|
||||
BOPTools::MapShapes(myDraftSolid, TopAbs_FACE, aMF);
|
||||
aItLS.Initialize(myLIF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aMF.Add(aFI);
|
||||
}
|
||||
// aME - Edges from DraftSolid [i.e. edges to stop]
|
||||
BOPTools::MapShapes(myDraftSolid, TopAbs_EDGE, aME);
|
||||
//
|
||||
// 3. Select boxes of faces that are not out of aBoxS
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(myBoxS);
|
||||
//
|
||||
aNbFP=myBBTree->Select(aSelector);
|
||||
const BOPCol_ListOfInteger& aLIFPx=aSelector.Indices();
|
||||
//
|
||||
// 4. aIVec, aLIFP - faces to process
|
||||
BOPCol_ListOfInteger aLIFP(aAlr1);
|
||||
BOPCol_NCVector<Standard_Integer> aIVec(256, aAlr1);
|
||||
//
|
||||
k=0;
|
||||
aItLI.Initialize(aLIFPx);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
nFP=aItLI.Value();
|
||||
const TopoDS_Shape& aFP=aVSB(nFP).Shape();
|
||||
if (!aMF.Contains(aFP)) {
|
||||
MapEdgesAndFaces(aFP, aMEFP, aAlr1);
|
||||
aLIFP.Append(nFP);
|
||||
aIVec.Append1()=nFP;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
aNbFP=k;
|
||||
//
|
||||
// sort indices
|
||||
std::sort(aIVec.begin(), aIVec.end());
|
||||
//
|
||||
// 5. Collect faces that are IN mySolid [ myLFIN ]
|
||||
for (k=0; k<aNbFP; ++k) {
|
||||
nFP = aIVec(k);
|
||||
const BOPAlgo_ShapeBox& aSBF=aVSB(nFP);
|
||||
const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
|
||||
//
|
||||
if (!aMFDone.Add(aFP)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
iIsIN=BOPTools_AlgoTools::IsInternalFace
|
||||
(aFP, myDraftSolid, aMEF, aTolPC, myContext);
|
||||
//
|
||||
aLFP.Clear();
|
||||
aLFP.Append(aFP);
|
||||
//
|
||||
aItLI1.Initialize(aLIFP);
|
||||
for (; aItLI1.More(); aItLI1.Next()) {
|
||||
const TopoDS_Shape& aFx=aVSB(aItLI1.Value()).Shape();
|
||||
if (!aMFDone.Contains(aFx)) {
|
||||
aLFP.Append(aFx);
|
||||
}
|
||||
}
|
||||
//
|
||||
aLCBF.Clear();
|
||||
//
|
||||
MakeConnexityBlock(aLFP, aME, aMFDone, aMEFP, aLCBF, aAlr1);
|
||||
//
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFx=aItLS.Value();
|
||||
aMFDone.Add(aFx);
|
||||
if (iIsIN) {
|
||||
myLFIN.Append(aFx);
|
||||
}
|
||||
}
|
||||
} // for (k=0; k<aNbFP; ++k) {
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
|
||||
(const TopoDS_Shape& aF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next()) {
|
||||
const TopoDS_Shape& aW=myItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
//
|
||||
if (aMEF.Contains(aE)) {
|
||||
BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
|
||||
aLF.Append(aF);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLS(theAllocator);
|
||||
//
|
||||
aLS.Append(aF);
|
||||
aMEF.Add(aE, aLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlock
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MakeConnexityBlock
|
||||
(const BOPCol_ListOfShape& theLFIn,
|
||||
const BOPCol_IndexedMapOfShape& theMEAvoid,
|
||||
const BOPCol_MapOfShape& aMFDone,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
const Handle(NCollection_BaseAllocator)& theAlr)
|
||||
{
|
||||
Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
|
||||
BOPCol_ListIteratorOfListOfShape aIt;
|
||||
//
|
||||
BOPCol_IndexedMapOfShape aMCB(100, theAlr);
|
||||
BOPCol_IndexedMapOfShape aMAdd(100, theAlr);
|
||||
BOPCol_IndexedMapOfShape aMAdd1(100, theAlr);
|
||||
//
|
||||
aNbF=theLFIn.Extent();
|
||||
//
|
||||
// 2. aMCB
|
||||
const TopoDS_Shape& aF1=theLFIn.First();
|
||||
aMAdd.Add(aF1);
|
||||
//
|
||||
for(;;) {
|
||||
aMAdd1.Clear();
|
||||
aNbAdd = aMAdd.Extent();
|
||||
for (i=1; i<=aNbAdd; ++i) {
|
||||
const TopoDS_Shape& aF=aMAdd(i);
|
||||
//
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next()) {
|
||||
const TopoDS_Shape& aW=myItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
if (theMEAvoid.Contains(aE)){
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
|
||||
aIt.Initialize(aLF);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aFx=aIt.Value();
|
||||
if (aFx.IsSame(aF)) {
|
||||
continue;
|
||||
}
|
||||
if (aMCB.Contains(aFx)) {
|
||||
continue;
|
||||
}
|
||||
if (aMFDone.Contains(aFx)) {
|
||||
continue;
|
||||
}
|
||||
aMAdd1.Add(aFx);
|
||||
}
|
||||
}// for (; myItW.More(); myItW.Next()) {
|
||||
}// for (; myItF.More(); myItF.Next()) {
|
||||
aMCB.Add(aF);
|
||||
}// for (i=1; i<=aNbAdd; ++i) {
|
||||
//
|
||||
aNbAdd1=aMAdd1.Extent();
|
||||
if (!aNbAdd1) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
aMAdd.Clear();
|
||||
for (i=1; i<=aNbAdd1; ++i) {
|
||||
const TopoDS_Shape& aFAdd=aMAdd1(i);
|
||||
aMAdd.Add(aFAdd);
|
||||
}
|
||||
//
|
||||
}//while(1) {
|
||||
//
|
||||
aNbF=aMCB.Extent();
|
||||
for (i=1; i<=aNbF; ++i) {
|
||||
const TopoDS_Shape& aF=aMCB(i);
|
||||
theLCB.Append(aF);
|
||||
}
|
||||
}
|
||||
//
|
||||
typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> \
|
||||
BOPAlgo_VectorOfFillIn3DParts;
|
||||
//
|
||||
typedef BOPCol_ContextFunctor
|
||||
<BOPAlgo_FillIn3DParts,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPCol_FillIn3DPartsFunctor;
|
||||
//
|
||||
typedef BOPCol_ContextCnt
|
||||
<BOPCol_FillIn3DPartsFunctor,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
|
||||
//
|
||||
//=======================================================================
|
||||
// class: BOPAlgo_Builder
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -540,156 +184,123 @@ void BOPAlgo_Builder::FillIn3DParts
|
||||
BOPCol_DataMapOfShapeShape& theDraftSolids,
|
||||
const BOPCol_BaseAllocator& )
|
||||
{
|
||||
Standard_Boolean bHasImage;
|
||||
Standard_Integer i, k, aNbS, aNbLIF, aNbFIN, aNbVSB, aNbVFIP;
|
||||
Handle(NCollection_BaseAllocator) aAlr0;
|
||||
TopoDS_Solid aSD;
|
||||
TopoDS_Iterator aIt;
|
||||
BRep_Builder aBB;
|
||||
//
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
//
|
||||
aAlr0=
|
||||
NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
//
|
||||
BOPCol_MapOfShape aMFence(100, aAlr0);
|
||||
BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
|
||||
//
|
||||
theDraftSolids.Clear();
|
||||
//
|
||||
// 1. aVSB vector Index/FaceBox
|
||||
aNbS=myDS->NbSourceShapes();
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType()!=TopAbs_FACE) {
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Find all faces that are IN solids
|
||||
|
||||
// Store boxes of the shapes into a map
|
||||
BOPCol_IndexedDataMapOfShapeBox aShapeBoxMap(1, anAlloc);
|
||||
|
||||
// Fence map
|
||||
BOPCol_MapOfShape aMFence(1, anAlloc);
|
||||
|
||||
// Get all faces
|
||||
TopTools_ListOfShape aLFaces(anAlloc);
|
||||
|
||||
Standard_Integer i, aNbS = myDS->NbSourceShapes();
|
||||
for (i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_FACE)
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
//
|
||||
if (myImages.IsBound(aS)) {
|
||||
const BOPCol_ListOfShape& aLS=myImages.Find(aS);
|
||||
aItLS.Initialize(aLS);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSx=aItLS.Value();
|
||||
if (!aMFence.Add(aSx)) {
|
||||
continue;
|
||||
}
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add(aSx, aBox);
|
||||
aBox.SetGap(aBox.GetGap() + Precision::Confusion());
|
||||
//
|
||||
BOPAlgo_ShapeBox& aSB=aVSB.Append1();
|
||||
aSB.SetShape(aSx);
|
||||
aSB.SetBox(aBox);
|
||||
|
||||
const TopoDS_Shape& aS = aSI.Shape();
|
||||
const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
|
||||
|
||||
if (pLSIm)
|
||||
{
|
||||
TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
|
||||
for (; aItLSIm.More(); aItLSIm.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSIm = aItLSIm.Value();
|
||||
if (aMFence.Add(aSIm))
|
||||
aLFaces.Append(aSIm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Bnd_Box& aBox=aSI.Box();
|
||||
//
|
||||
BOPAlgo_ShapeBox& aSB=aVSB.Append1();
|
||||
aSB.SetShape(aS);
|
||||
aSB.SetBox(aBox);
|
||||
else
|
||||
{
|
||||
aLFaces.Append(aS);
|
||||
aShapeBoxMap.Add(aS, aSI.Box());
|
||||
}
|
||||
}//for (i=0; i<aNbS; ++i) {
|
||||
aMFence.Clear();
|
||||
//
|
||||
// 1.2. Prepare TreeFiller
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box>
|
||||
aTreeFiller(aBBTree);
|
||||
//
|
||||
aNbVSB=aVSB.Extent();
|
||||
for (k=0; k<aNbVSB; ++k) {
|
||||
const BOPAlgo_ShapeBox& aSBk=aVSB(k);
|
||||
const Bnd_Box& aBk=aSBk.Box();
|
||||
//
|
||||
aTreeFiller.Add(k, aBk);
|
||||
}
|
||||
//
|
||||
// 1.3. Shake TreeFiller
|
||||
aTreeFiller.Fill();
|
||||
//
|
||||
//---------------------------------------------
|
||||
// 2. Solids
|
||||
BOPAlgo_VectorOfFillIn3DParts aVFIP;
|
||||
//
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
||||
|
||||
BRep_Builder aBB;
|
||||
|
||||
// Get all solids
|
||||
TopTools_ListOfShape aLSolids(anAlloc);
|
||||
// Keep INTERNAL faces of the solids
|
||||
BOPCol_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
|
||||
// Draft solids
|
||||
BOPCol_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
|
||||
|
||||
for (i = 0; i < aNbS; ++i)
|
||||
{
|
||||
BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_SOLID)
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
|
||||
//
|
||||
// 2.0 Flag bHasImage
|
||||
bHasImage=Standard_False;
|
||||
aIt.Initialize(aS);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aShell=aIt.Value();
|
||||
bHasImage=myImages.IsBound(aShell);
|
||||
if (bHasImage){
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2.1 Bounding box for the solid aS [ aBoxS ]
|
||||
Bnd_Box aBoxS;
|
||||
aBoxS=aSI.Box();
|
||||
//
|
||||
// 2.2 Build Draft Solid [aSD]
|
||||
BOPCol_ListOfShape aLIF;
|
||||
|
||||
const TopoDS_Shape& aS = aSI.Shape();
|
||||
const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
|
||||
//
|
||||
// Bounding box for the solid aS
|
||||
const Bnd_Box& aBoxS = aSI.Box();
|
||||
|
||||
// Build Draft Solid
|
||||
TopTools_ListOfShape aLIF;
|
||||
TopoDS_Solid aSD;
|
||||
aBB.MakeSolid(aSD);
|
||||
BuildDraftSolid(aSolid, aSD, aLIF);
|
||||
//
|
||||
BOPAlgo_FillIn3DParts& aFIP=aVFIP.Append1();
|
||||
//
|
||||
aFIP.SetSolid(aSolid);
|
||||
aFIP.SetDraftSolid(aSD);
|
||||
aFIP.SetHasImage(bHasImage);
|
||||
aFIP.SetBoxS(aBoxS);
|
||||
aFIP.SetLIF(aLIF);
|
||||
aFIP.SetBBTree(aBBTree);
|
||||
aFIP.SetVSB(aVSB);
|
||||
}//for (i=0; i<aNbS; ++i) {
|
||||
//
|
||||
aNbVFIP=aVFIP.Extent();
|
||||
//================================================================
|
||||
BOPAlgo_FillIn3DPartsCnt::Perform(myRunParallel, aVFIP, myContext);
|
||||
//================================================================
|
||||
for (k=0; k<aNbVFIP; ++k) {
|
||||
BOPAlgo_FillIn3DParts& aFIP=aVFIP(k);
|
||||
bHasImage=aFIP.HasImage();
|
||||
const TopoDS_Solid& aSolid=aFIP.Solid();
|
||||
const TopoDS_Solid& aSDraft =aFIP.DraftSolid();
|
||||
const BOPCol_ListOfShape& aLFIN=aFIP.LFIN();
|
||||
const BOPCol_ListOfShape& aLIF=aFIP.LIF();
|
||||
//
|
||||
aNbLIF=aLIF.Extent();
|
||||
//
|
||||
// Store the results in theInParts, theDraftSolids
|
||||
BOPCol_ListOfShape aLFINx;
|
||||
//
|
||||
aNbFIN=aLFIN.Extent();
|
||||
if (aNbFIN || aNbLIF) {
|
||||
aItLS.Initialize(aLFIN);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFINx.Append(aFI);
|
||||
}
|
||||
aItLS.Initialize(aLIF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFINx.Append(aFI);
|
||||
}
|
||||
theInParts.Bind(aSolid, aLFINx);
|
||||
|
||||
aLSolids.Append(aSD);
|
||||
aSolidsIF.Bind(aSD, aLIF);
|
||||
aShapeBoxMap.Add(aSD, aBoxS);
|
||||
aDraftSolid.Add(aS, aSD);
|
||||
}
|
||||
|
||||
// Perform classification of the faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape anInParts;
|
||||
|
||||
BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
|
||||
myContext, anInParts, &aShapeBoxMap, &aSolidsIF);
|
||||
|
||||
// Analyze the results of classification
|
||||
Standard_Integer aNbSol = aDraftSolid.Extent();
|
||||
for (i = 1; i <= aNbSol; ++i)
|
||||
{
|
||||
const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
|
||||
const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
|
||||
const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
|
||||
const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
|
||||
|
||||
Standard_Integer aNbIN = aLInFaces.Extent();
|
||||
|
||||
if (!aNbIN)
|
||||
{
|
||||
Standard_Boolean bHasImage = Standard_False;
|
||||
// Check if the shells of the solid have image
|
||||
for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
|
||||
bHasImage = myImages.IsBound(it.Value());
|
||||
|
||||
if (!bHasImage)
|
||||
// no need to split the solid
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (aNbFIN || bHasImage) {
|
||||
theDraftSolids.Bind(aSolid, aSDraft);
|
||||
|
||||
theDraftSolids.Bind(aSolid, aSDraft);
|
||||
|
||||
Standard_Integer aNbInt = aLInternal.Extent();
|
||||
if (aNbInt || aNbIN)
|
||||
{
|
||||
// Combine the lists
|
||||
TopTools_ListOfShape *pLIN = theInParts.Bound(aSolid, TopTools_ListOfShape());
|
||||
|
||||
TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
pLIN->Append(aItLS.Value());
|
||||
|
||||
aItLS.Initialize(aLInternal);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
pLIN->Append(aItLS.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -54,7 +54,8 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
|
||||
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
|
||||
(const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
:
|
||||
BOPAlgo_Algo(theAllocator)
|
||||
BOPAlgo_Algo(theAllocator),
|
||||
myFPBDone(1, theAllocator)
|
||||
{
|
||||
myDS = NULL;
|
||||
myIterator = NULL;
|
||||
@@ -286,6 +287,13 @@ void BOPAlgo_PaveFiller::PerformInternal()
|
||||
UpdatePaveBlocksWithSDVertices();
|
||||
UpdateInterfsWithSDVertices();
|
||||
//
|
||||
// Force intersection of edges after increase
|
||||
// of the tolerance values of their vertices
|
||||
//ForceInterfEE();
|
||||
// Force Edge/Face intersection after increase
|
||||
// of the tolerance values of their vertices
|
||||
ForceInterfEF();
|
||||
//
|
||||
// 22
|
||||
PerformFF();
|
||||
if (HasErrors()) {
|
||||
|
@@ -167,6 +167,9 @@ protected:
|
||||
Bnd_Box,
|
||||
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockBndBox;
|
||||
|
||||
typedef NCollection_DataMap
|
||||
<Standard_Integer,
|
||||
BOPDS_MapOfPaveBlock> BOPAlgo_DataMapOfIntegerMapOfPaveBlock;
|
||||
|
||||
//! Sets non-destructive mode automatically if an argument
|
||||
//! contains a locked sub-shape (see TopoDS_Shape::Locked()).
|
||||
@@ -474,6 +477,19 @@ protected:
|
||||
//! In case self-interference is found the warning is added.
|
||||
Standard_EXPORT void CheckSelfInterference();
|
||||
|
||||
//! The method looks for the additional common blocks among pairs of edges
|
||||
//! with the same bounding vertices.
|
||||
Standard_EXPORT void ForceInterfEE();
|
||||
|
||||
//! The method looks for the additional edge/face common blocks
|
||||
//! among pairs of edge/face having the same vertices.
|
||||
Standard_EXPORT void ForceInterfEF();
|
||||
|
||||
//! Performs intersection of given pave blocks
|
||||
//! with all faces from arguments.
|
||||
Standard_EXPORT void ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
|
||||
const Standard_Boolean theAddInterf);
|
||||
|
||||
|
||||
BOPCol_ListOfShape myArguments;
|
||||
BOPDS_PDS myDS;
|
||||
@@ -485,6 +501,8 @@ protected:
|
||||
Standard_Boolean myAvoidBuildPCurve;
|
||||
BOPAlgo_GlueEnum myGlue;
|
||||
|
||||
BOPAlgo_DataMapOfIntegerMapOfPaveBlock myFPBDone; //!< Fence map of intersected faces and pave blocks
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -768,3 +768,278 @@ Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
|
||||
}
|
||||
return bValid;
|
||||
}
|
||||
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEE
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEE()
|
||||
{
|
||||
// Now that we have vertices increased and unified, try to find additional
|
||||
// common blocks among the pairs of edges.
|
||||
// Since all real intersections should have already happened, here we
|
||||
// are interested in common blocks only, thus we need to check only
|
||||
// those pairs of pave blocks with the same bounding vertices.
|
||||
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Initialize pave blocks for all vertices which participated in intersections
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() == TopAbs_VERTEX)
|
||||
{
|
||||
if (myDS->HasInterf(i))
|
||||
myDS->InitPaveBlocksForVertex(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the connection map from bounding vertices to pave blocks
|
||||
// having those bounding vertices
|
||||
NCollection_IndexedDataMap<BOPDS_Pair,
|
||||
BOPDS_ListOfPaveBlock,
|
||||
BOPDS_PairMapHasher> aPBMap(1, anAlloc);
|
||||
// Fence map of pave blocks
|
||||
BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_EDGE)
|
||||
// Not an edge
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Edge has no pave blocks
|
||||
continue;
|
||||
|
||||
if (aSI.HasFlag())
|
||||
// Degenerated edge
|
||||
continue;
|
||||
|
||||
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(i);
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
|
||||
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
|
||||
if (!aMPBFence.Add(aPBR))
|
||||
continue;
|
||||
|
||||
// Get indices
|
||||
Standard_Integer nV1, nV2;
|
||||
aPBR->Indices(nV1, nV2);
|
||||
|
||||
// Add pave block to a map
|
||||
BOPDS_Pair aPair(nV1, nV2);
|
||||
BOPDS_ListOfPaveBlock *pList = aPBMap.ChangeSeek(aPair);
|
||||
if (!pList)
|
||||
pList = &aPBMap(aPBMap.Add(aPair, BOPDS_ListOfPaveBlock(anAlloc)));
|
||||
pList->Append(aPBR);
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbPB = aPBMap.Extent();
|
||||
if (!aNbPB)
|
||||
return;
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Prepare pave blocks with the same vertices for intersection.
|
||||
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
|
||||
|
||||
for (Standard_Integer i = 1; i <= aNbPB; ++i)
|
||||
{
|
||||
const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i);
|
||||
if (aLPB.Extent() < 2)
|
||||
continue;
|
||||
|
||||
const BOPDS_Pair& aPair = aPBMap.FindKey(i);
|
||||
Standard_Integer nV1, nV2;
|
||||
aPair.Indices(nV1, nV2);
|
||||
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// Use the max tolerance of vertices as Fuzzy value for intersection of edges.
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
// All possible pairs combined from the list <aLPB> should be checked
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
|
||||
for (; aItLPB1.More(); aItLPB1.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value();
|
||||
const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1);
|
||||
const Standard_Integer nE1 = aPB1->OriginalEdge();
|
||||
const Standard_Integer iR1 = myDS->Rank(nE1);
|
||||
const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1));
|
||||
Standard_Real aT11, aT12;
|
||||
aPB1->Range(aT11, aT12);
|
||||
BRepAdaptor_Curve aBAC1(aE1);
|
||||
gp_Pnt aPm;
|
||||
gp_Vec aVTgt1;
|
||||
aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1);
|
||||
if (aVTgt1.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
aVTgt1.Normalize();
|
||||
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1;
|
||||
for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value();
|
||||
const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2);
|
||||
const Standard_Integer nE2 = aPB2->OriginalEdge();
|
||||
const Standard_Integer iR2 = myDS->Rank(nE2);
|
||||
|
||||
// Check that the edges came from different arguments
|
||||
if (iR1 == iR2)
|
||||
{
|
||||
// If the sharing of the vertices is not original, but has been acquired
|
||||
// during the operation, check the coincidence of the edges even if
|
||||
// they came from the same argument
|
||||
if ((!myDS->IsNewShape(nV1) && (myDS->Rank(nV1) == iR1)) ||
|
||||
(!myDS->IsNewShape(nV2) && (myDS->Rank(nV2) == iR2)))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the Pave blocks do not form the Common block already
|
||||
if (!aCB1.IsNull() && !aCB2.IsNull())
|
||||
{
|
||||
if (aCB1 == aCB2)
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2));
|
||||
Standard_Real aT21, aT22;
|
||||
aPB2->Range(aT21, aT22);
|
||||
|
||||
// Check the angle between edges in the middle point.
|
||||
// If the angle is more than 10 degrees, do not use the additional
|
||||
// tolerance, as it may lead to undesired unification of edges
|
||||
Standard_Boolean bUseAddTol = Standard_True;
|
||||
{
|
||||
BRepAdaptor_Curve aBAC2(aE2);
|
||||
if (aBAC1.GetType() != GeomAbs_Line ||
|
||||
aBAC2.GetType() != GeomAbs_Line)
|
||||
{
|
||||
GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
|
||||
aProjPC.Perform(aPm);
|
||||
if (!aProjPC.NbPoints())
|
||||
continue;
|
||||
|
||||
gp_Pnt aPm2;
|
||||
gp_Vec aVTgt2;
|
||||
aBAC2.D1(aProjPC.LowerDistanceParameter(), aPm2, aVTgt2);
|
||||
if (aVTgt2.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
// The angle should be close to zero
|
||||
Standard_Real aCos = aVTgt1.Dot (aVTgt2.Normalized());
|
||||
if (Abs(aCos) < 0.9848)
|
||||
bUseAddTol = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Add pair for intersection
|
||||
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge.Append1();
|
||||
anEdgeEdge.UseQuickCoincidenceCheck(Standard_True);
|
||||
anEdgeEdge.SetPaveBlock1(aPB1);
|
||||
anEdgeEdge.SetPaveBlock2(aPB2);
|
||||
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
|
||||
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
|
||||
//anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
|
||||
if (bUseAddTol)
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
else
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
|
||||
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbPairs = aVEdgeEdge.Length();
|
||||
if (!aNbPairs)
|
||||
return;
|
||||
|
||||
aPBMap.Clear();
|
||||
aMPBFence.Clear();
|
||||
anAlloc->Reset();
|
||||
|
||||
// Perform intersection of the found pairs
|
||||
BOPAlgo_EdgeEdgeCnt::Perform (myRunParallel, aVEdgeEdge);
|
||||
|
||||
BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
|
||||
if (aEEs.IsEmpty())
|
||||
aEEs.SetIncrement(10);
|
||||
|
||||
// Analyze the results of intersection looking for TopAbs_EDGE
|
||||
// intersection type only.
|
||||
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbPairs; ++i)
|
||||
{
|
||||
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i);
|
||||
if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors())
|
||||
{
|
||||
// Warn about failed intersection of sub-shapes
|
||||
//const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge());
|
||||
//const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge());
|
||||
//AddIntersectionFailedWarning(aE1, aE2);
|
||||
continue;
|
||||
}
|
||||
|
||||
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeEdge.CommonParts();
|
||||
if (aCParts.Length() != 1)
|
||||
continue;
|
||||
|
||||
const IntTools_CommonPrt& aCP = aCParts(1);
|
||||
if (aCP.Type() != TopAbs_EDGE)
|
||||
continue;
|
||||
|
||||
Handle(BOPDS_PaveBlock) aPB[] = {anEdgeEdge.PaveBlock1(), anEdgeEdge.PaveBlock2()};
|
||||
const Standard_Integer nE1 = aPB[0]->OriginalEdge();
|
||||
const Standard_Integer nE2 = aPB[1]->OriginalEdge();
|
||||
|
||||
if (myDS->Rank(nE1) == myDS->Rank(nE2))
|
||||
{
|
||||
// Add acquired self-interference warning
|
||||
//TopoDS_Compound aWC;
|
||||
//BRep_Builder().MakeCompound(aWC);
|
||||
//BRep_Builder().Add(aWC, myDS->Shape(nE1));
|
||||
//BRep_Builder().Add(aWC, myDS->Shape(nE2));
|
||||
//AddWarning(new BOPAlgo_AlertAcquiredSelfIntersection(aWC));
|
||||
}
|
||||
|
||||
BOPDS_InterfEE& aEE = aEEs.Append1();
|
||||
aEE.SetIndices(nE1, nE2);
|
||||
aEE.SetCommonPart(aCP);
|
||||
myDS->AddInterf(nE1, nE2);
|
||||
|
||||
// Fill map for common blocks creation
|
||||
for (Standard_Integer j = 0; j < 2; ++j)
|
||||
{
|
||||
if (myDS->IsCommonBlock(aPB[j]))
|
||||
{
|
||||
const BOPDS_ListOfPaveBlock& aLPBCB = myDS->CommonBlock(aPB[j])->PaveBlocks();
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
|
||||
TColStd_MapTransientHasher>(aPB[j], aItLPB.Value(), aMPBLPB, anAlloc);
|
||||
}
|
||||
}
|
||||
BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
|
||||
TColStd_MapTransientHasher>(aPB[0], aPB[1], aMPBLPB, anAlloc);
|
||||
}
|
||||
|
||||
// Create new common blocks of coinciding pairs.
|
||||
BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, anAlloc, myDS);
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <BOPAlgo_PaveFiller.hxx>
|
||||
#include <BOPAlgo_Alerts.hxx>
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_MapOfInteger.hxx>
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
@@ -33,9 +34,11 @@
|
||||
#include <BOPDS_Pave.hxx>
|
||||
#include <BOPDS_PaveBlock.hxx>
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_AlgoTools2D.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <IntTools_CommonPrt.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
@@ -43,12 +46,15 @@
|
||||
#include <IntTools_Range.hxx>
|
||||
#include <IntTools_SequenceOfCommonPrts.hxx>
|
||||
#include <IntTools_Tools.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_EdgeFace
|
||||
//purpose :
|
||||
@@ -247,7 +253,12 @@ void BOPAlgo_PaveFiller::PerformEF()
|
||||
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
|
||||
aEdgeFace.SetRange (aPBRange);
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
//
|
||||
|
||||
// Save the pair to avoid their forced intersection
|
||||
BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
|
||||
if (!pMPB)
|
||||
pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
|
||||
pMPB->Add(aPB);
|
||||
}//for (; aIt.More(); aIt.Next()) {
|
||||
}//for (; myIterator->More(); myIterator->Next()) {
|
||||
//
|
||||
@@ -656,3 +667,351 @@ void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF()
|
||||
{
|
||||
if (!myIsPrimary)
|
||||
return;
|
||||
|
||||
// Now that we have vertices increased and unified, try to find additional
|
||||
// edge/face common blocks among the pairs of edge/face.
|
||||
// Here, we are interested in common blocks only, as all real intersections
|
||||
// should have happened already. Thus, we need to check only those pairs
|
||||
// of edge/face which have the same vertices.
|
||||
|
||||
// Collect all pave blocks
|
||||
BOPDS_IndexedMapOfPaveBlock aMPB;
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nE = 0; nE < aNbS; ++nE)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
|
||||
if (aSI.ShapeType() != TopAbs_EDGE)
|
||||
// Not an edge
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Edge has no pave blocks
|
||||
continue;
|
||||
|
||||
if (aSI.HasFlag())
|
||||
// Degenerated edge
|
||||
continue;
|
||||
|
||||
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
|
||||
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
|
||||
aMPB.Add(aPBR);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform intersection of collected pave blocks with faces
|
||||
ForceInterfEF(aMPB, Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
|
||||
const Standard_Boolean theAddInterf)
|
||||
{
|
||||
if (theMPB.IsEmpty())
|
||||
return;
|
||||
|
||||
// Fill the tree with bounding boxes of the pave blocks
|
||||
NCollection_UBTree<Standard_Integer, Bnd_Box> aBBTree;
|
||||
NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
|
||||
|
||||
Standard_Integer aNbPB = theMPB.Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
|
||||
{
|
||||
Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
|
||||
if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB))
|
||||
{
|
||||
FillShrunkData(aPB);
|
||||
if (!aPB->HasShrunkData())
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Real f, l;
|
||||
Bnd_Box aPBBox;
|
||||
Standard_Boolean isSplit;
|
||||
aPB->ShrunkData(f, l, aPBBox, isSplit);
|
||||
|
||||
aTreeFiller.Add(aPBMap.Add(aPB), aPBBox);
|
||||
}
|
||||
|
||||
// Shake the tree
|
||||
aTreeFiller.Fill();
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Find pairs of Face/PaveBlock containing the same vertices
|
||||
// and prepare those pairs for intersection.
|
||||
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
|
||||
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nF = 0; nF < aNbS; ++nF)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
|
||||
if (aSI.ShapeType() != TopAbs_FACE)
|
||||
// Not a face
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Face has no face info
|
||||
continue;
|
||||
|
||||
const Bnd_Box& aBoxF = aSI.Box();
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(aBoxF);
|
||||
|
||||
if (!aBBTree.Select(aSelector))
|
||||
continue;
|
||||
|
||||
const TopoDS_Face& aF = TopoDS::Face(aSI.Shape());
|
||||
const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
|
||||
// Vertices of the face
|
||||
BOPCol_MapOfInteger aMVF;
|
||||
const BOPCol_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
|
||||
&aFI.VerticesIn(),
|
||||
&aFI.VerticesSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
BOPCol_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
|
||||
for (; itM.More(); itM.Next())
|
||||
aMVF.Add(itM.Value());
|
||||
}
|
||||
|
||||
// Pave Blocks of the face
|
||||
const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
|
||||
&aFI.PaveBlocksIn(),
|
||||
&aFI.PaveBlocksSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
const Standard_Integer aNb = pMPBF[iM]->Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
|
||||
aMVF.Add(aPB->Pave1().Index());
|
||||
aMVF.Add(aPB->Pave2().Index());
|
||||
}
|
||||
}
|
||||
|
||||
// Projection tool
|
||||
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
|
||||
BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF);
|
||||
|
||||
// Iterate on pave blocks and combine pairs containing
|
||||
// the same vertices
|
||||
const BOPCol_ListOfInteger& aLIPB = aSelector.Indices();
|
||||
BOPCol_ListOfInteger::Iterator itLIPB(aLIPB);
|
||||
for (; itLIPB.More(); itLIPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
|
||||
if (pMPBF[0]->Contains(aPB) ||
|
||||
pMPBF[1]->Contains(aPB) ||
|
||||
pMPBF[2]->Contains(aPB))
|
||||
continue;
|
||||
|
||||
// Check if the face contains both vertices of the pave block
|
||||
Standard_Integer nV1, nV2;
|
||||
aPB->Indices(nV1, nV2);
|
||||
if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
|
||||
// Face does not contain the vertices
|
||||
continue;
|
||||
|
||||
// Get the edge
|
||||
Standard_Integer nE;
|
||||
if (!aPB->HasEdge(nE))
|
||||
{
|
||||
nE = aPB->OriginalEdge();
|
||||
if (nE < 0)
|
||||
continue;
|
||||
|
||||
// Make sure that the edge and face came from different arguments
|
||||
if (myDS->Rank(nF) == myDS->Rank(nE))
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
|
||||
BRepAdaptor_Curve aBAC(aE);
|
||||
|
||||
// Check directions coincidence at middle point on the edge
|
||||
// and projection of that point on the face.
|
||||
// If the angle between tangent vector to the curve and normal
|
||||
// of the face is not in the range of 65 - 115 degrees, do not use the additional
|
||||
// tolerance, as it may lead to undesired unification of edge with the face.
|
||||
Standard_Boolean bUseAddTol = Standard_True;
|
||||
|
||||
Standard_Real aTS[2];
|
||||
Bnd_Box aPBBox;
|
||||
Standard_Boolean isSplit;
|
||||
aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit);
|
||||
|
||||
// Middle point
|
||||
gp_Pnt aPOnE;
|
||||
// Tangent vector in the middle point
|
||||
gp_Vec aVETgt;
|
||||
aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
|
||||
if (aVETgt.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
aProjPS.Perform(aPOnE);
|
||||
if (!aProjPS.NbPoints())
|
||||
continue;
|
||||
|
||||
// Check the distance in the middle point, using the max vertices
|
||||
// tolerance as the criteria.
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
|
||||
continue;
|
||||
|
||||
Standard_Real U, V;
|
||||
aProjPS.LowerDistanceParameters(U, V);
|
||||
if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
|
||||
continue;
|
||||
|
||||
if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
|
||||
aBAC.GetType() != GeomAbs_Line)
|
||||
{
|
||||
gp_Pnt aPOnS = aProjPS.NearestPoint();
|
||||
gp_Vec aVFNorm(aPOnS, aPOnE);
|
||||
if (aVFNorm.SquareMagnitude() > gp::Resolution())
|
||||
{
|
||||
// Angle between vectors should be close to 90 degrees.
|
||||
// We allow deviation of 10 degrees.
|
||||
Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
|
||||
if (Abs(aCos) > 0.17365)
|
||||
bUseAddTol = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute an addition to Fuzzy value
|
||||
Standard_Real aTolAdd = 0.0;
|
||||
if (bUseAddTol)
|
||||
{
|
||||
// Compute the distance from the bounding points of the edge
|
||||
// to the face and use the maximal of these distances as a
|
||||
// fuzzy tolerance for the intersection.
|
||||
// Use the maximal tolerance of the pave block's vertices
|
||||
// as a max criteria for the computed distance.
|
||||
|
||||
for (Standard_Integer iP = 0; iP < 2; ++iP)
|
||||
{
|
||||
gp_Pnt aP = aBAC.Value(aTS[iP]);
|
||||
aProjPS.Perform(aP);
|
||||
if (aProjPS.NbPoints())
|
||||
{
|
||||
Standard_Real aDistEF = aProjPS.LowerDistance();
|
||||
if (aDistEF < aTolCheck && aDistEF > aTolAdd)
|
||||
aTolAdd = aDistEF;
|
||||
}
|
||||
}
|
||||
if (aTolAdd > 0.)
|
||||
{
|
||||
aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
|
||||
if (aTolAdd < 0.)
|
||||
aTolAdd = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean bIntersect = aTolAdd > 0;
|
||||
if (!bIntersect)
|
||||
{
|
||||
const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
|
||||
bIntersect = !pMPB || !(pMPB->Contains(aPB));
|
||||
}
|
||||
|
||||
if (bIntersect)
|
||||
{
|
||||
// Prepare pair for intersection
|
||||
BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Append1();
|
||||
aEdgeFace.SetIndices(nE, nF);
|
||||
aEdgeFace.SetPaveBlock(aPB);
|
||||
aEdgeFace.SetEdge(aE);
|
||||
aEdgeFace.SetFace(aF);
|
||||
//aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
|
||||
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
|
||||
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbEFs = aVEdgeFace.Length();
|
||||
if (!aNbEFs)
|
||||
return;
|
||||
|
||||
aPBMap.Clear();
|
||||
anAlloc->Reset();
|
||||
|
||||
// Perform intersection of the found pairs
|
||||
BOPAlgo_EdgeFaceCnt::Perform (myRunParallel, aVEdgeFace, myContext);
|
||||
|
||||
BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
|
||||
if (theAddInterf && aEFs.IsEmpty())
|
||||
aEFs.SetIncrement(10);
|
||||
|
||||
// Analyze the results of intersection looking for TopAbs_EDGE
|
||||
// intersection type only.
|
||||
|
||||
// Collect all pairs for common block creation
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbEFs; ++i)
|
||||
{
|
||||
BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
|
||||
if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors())
|
||||
continue;
|
||||
|
||||
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
|
||||
if (aCParts.Length() != 1)
|
||||
continue;
|
||||
|
||||
const IntTools_CommonPrt& aCP = aCParts(1);
|
||||
if (aCP.Type() != TopAbs_EDGE)
|
||||
continue;
|
||||
|
||||
Standard_Integer nE, nF;
|
||||
anEdgeFace.Indices(nE, nF);
|
||||
if (theAddInterf)
|
||||
{
|
||||
// Add interference
|
||||
BOPDS_InterfEF& aEF = aEFs.Append1();
|
||||
aEF.SetIndices(nE, nF);
|
||||
aEF.SetCommonPart(aCP);
|
||||
myDS->AddInterf(nE, nF);
|
||||
}
|
||||
|
||||
const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
|
||||
// Update face information with new IN pave block
|
||||
myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
|
||||
if (theAddInterf)
|
||||
// Fill map for common blocks creation
|
||||
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
|
||||
}
|
||||
|
||||
if (aMPBLI.Extent())
|
||||
// Create new common blocks for coinciding pairs
|
||||
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
@@ -38,6 +39,8 @@
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
|
||||
#include <BRepBndLib.hxx>
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
@@ -64,10 +67,13 @@
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_AlgoTools2D.hxx>
|
||||
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
|
||||
#include <IntTools_Context.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
typedef NCollection_IndexedDataMap
|
||||
<TopoDS_Shape, gp_Dir, TopTools_ShapeMapHasher> BOPAlgo_IndexedDataMapOfShapeDir;
|
||||
typedef NCollection_IndexedDataMap
|
||||
@@ -1088,3 +1094,537 @@ void BOPAlgo_Tools::IntersectVertices(const BOPCol_IndexedDataMapOfShapeReal& th
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// Classification of the faces relatively solids
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_ShapeBox
|
||||
//purpose : Auxiliary class defining ShapeBox structure
|
||||
//=======================================================================
|
||||
class BOPAlgo_ShapeBox
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
BOPAlgo_ShapeBox() {};
|
||||
//! Sets the shape
|
||||
void SetShape(const TopoDS_Shape& theS)
|
||||
{
|
||||
myShape = theS;
|
||||
};
|
||||
//! Returns the shape
|
||||
const TopoDS_Shape& Shape() const
|
||||
{
|
||||
return myShape;
|
||||
};
|
||||
//! Sets the bounding box
|
||||
void SetBox(const Bnd_Box& theBox)
|
||||
{
|
||||
myBox = theBox;
|
||||
};
|
||||
//! Returns the bounding box
|
||||
const Bnd_Box& Box() const
|
||||
{
|
||||
return myBox;
|
||||
};
|
||||
private:
|
||||
TopoDS_Shape myShape;
|
||||
Bnd_Box myBox;
|
||||
};
|
||||
// Vector of ShapeBox
|
||||
typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_FillIn3DParts
|
||||
//purpose : Auxiliary class for faces classification in parallel mode
|
||||
//=======================================================================
|
||||
class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo
|
||||
{
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Constructor
|
||||
BOPAlgo_FillIn3DParts()
|
||||
{
|
||||
myBBTree = NULL;
|
||||
myVShapeBox = NULL;
|
||||
};
|
||||
|
||||
//! Destructor
|
||||
virtual ~BOPAlgo_FillIn3DParts() {};
|
||||
|
||||
//! Sets the solid
|
||||
void SetSolid(const TopoDS_Solid& theSolid)
|
||||
{
|
||||
mySolid = theSolid;
|
||||
};
|
||||
|
||||
//! Returns the solid
|
||||
const TopoDS_Solid& Solid() const
|
||||
{
|
||||
return mySolid;
|
||||
};
|
||||
|
||||
//! Sets the box for the solid
|
||||
void SetBoxS(const Bnd_Box& theBox)
|
||||
{
|
||||
myBoxS = theBox;
|
||||
};
|
||||
|
||||
//! Returns the solid's box
|
||||
const Bnd_Box& BoxS() const
|
||||
{
|
||||
return myBoxS;
|
||||
};
|
||||
|
||||
//! Sets own INTERNAL faces of the solid
|
||||
void SetOwnIF(const BOPCol_ListOfShape& theLIF)
|
||||
{
|
||||
myOwnIF = theLIF;
|
||||
};
|
||||
|
||||
//! Returns own INTERNAL faces of the solid
|
||||
const BOPCol_ListOfShape& OwnIF() const
|
||||
{
|
||||
return myOwnIF;
|
||||
};
|
||||
|
||||
//! Sets the Bounding Box tree
|
||||
void SetBBTree(const BOPCol_BoxBndTree& theBBTree)
|
||||
{
|
||||
myBBTree = (BOPCol_BoxBndTree*)&theBBTree;
|
||||
};
|
||||
|
||||
//! Sets the ShapeBox structure
|
||||
void SetShapeBoxVector(const BOPAlgo_VectorOfShapeBox& theShapeBox)
|
||||
{
|
||||
myVShapeBox = (BOPAlgo_VectorOfShapeBox*)&theShapeBox;
|
||||
};
|
||||
|
||||
//! Sets the context
|
||||
void SetContext(const Handle(IntTools_Context)& theContext)
|
||||
{
|
||||
myContext = theContext;
|
||||
}
|
||||
|
||||
//! Returns the context
|
||||
const Handle(IntTools_Context)& Context() const
|
||||
{
|
||||
return myContext;
|
||||
}
|
||||
|
||||
//! Performs the classification
|
||||
virtual void Perform();
|
||||
|
||||
//! Returns the faces classified as IN for solid
|
||||
const BOPCol_ListOfShape& InFaces() const
|
||||
{
|
||||
return myInFaces;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
//! Prepares Edge-Face connection map of the given shape
|
||||
void MapEdgesAndFaces(const TopoDS_Shape& theF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
const Handle(NCollection_BaseAllocator)& theAlloc);
|
||||
|
||||
//! Makes the connexity block of faces using the connection map
|
||||
void MakeConnexityBlock(const TopoDS_Face& theF,
|
||||
const BOPCol_IndexedMapOfShape& theMEToAvoid,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
BOPCol_MapOfShape& theMFDone,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
TopoDS_Face& theFaceToClassify);
|
||||
|
||||
TopoDS_Solid mySolid; //! Solid
|
||||
Bnd_Box myBoxS; // Bounding box of the solid
|
||||
BOPCol_ListOfShape myOwnIF; //! Own INTERNAL faces of the solid
|
||||
BOPCol_ListOfShape myInFaces; //! Faces classified as IN
|
||||
|
||||
BOPCol_BoxBndTree* myBBTree; //! UB tree of bounding boxes
|
||||
BOPAlgo_VectorOfShapeBox* myVShapeBox; //! ShapeBoxMap
|
||||
|
||||
TopoDS_Iterator myItF; //! Iterators
|
||||
TopoDS_Iterator myItW;
|
||||
|
||||
Handle(IntTools_Context) myContext; //! Context
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FillIn3DParts::Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::Perform()
|
||||
{
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
|
||||
myInFaces.Clear();
|
||||
|
||||
// 1. Select boxes of faces that are not out of aBoxS
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(myBoxS);
|
||||
//
|
||||
if (!myBBTree->Select(aSelector))
|
||||
return;
|
||||
|
||||
const BOPCol_ListOfInteger& aLIFP = aSelector.Indices();
|
||||
|
||||
// 2. Fill maps of edges and faces of the solid
|
||||
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
BOPAlgo_VectorOfShapeBox& aVShapeBox = *myVShapeBox;
|
||||
|
||||
BOPCol_IndexedMapOfShape aMSE(1, anAlloc), aMSF(1, anAlloc);
|
||||
BOPTools::MapShapes(mySolid, TopAbs_EDGE, aMSE);
|
||||
BOPTools::MapShapes(mySolid, TopAbs_FACE, aMSF);
|
||||
|
||||
// Check if the Solid contains any faces
|
||||
Standard_Boolean bIsEmpty = aMSF.IsEmpty();
|
||||
|
||||
// Add own internal faces of the solid into aMSF
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(myOwnIF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
aMSF.Add(aItLS.Value());
|
||||
|
||||
// 3. aIVec - faces to process.
|
||||
// Filter the selected faces with faces of the solid.
|
||||
BOPCol_NCVector<Standard_Integer> aIVec(256, anAlloc);
|
||||
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI(aLIFP);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
Standard_Integer nFP = aItLI.Value();
|
||||
const TopoDS_Shape& aFP = aVShapeBox(nFP).Shape();
|
||||
if (!aMSF.Contains(aFP))
|
||||
aIVec.Append1() = nFP;
|
||||
}
|
||||
|
||||
// 4. Classify faces relatively solid.
|
||||
// Store faces that are IN mySolid into <myInFaces>
|
||||
|
||||
Standard_Integer k, aNbFP = aIVec.Length();
|
||||
// Sort indices if necessary
|
||||
if (aNbFP > 1)
|
||||
std::sort(aIVec.begin(), aIVec.end());
|
||||
|
||||
if (bIsEmpty)
|
||||
{
|
||||
// The solid is empty as it does not contain any faces.
|
||||
// It could happen when the input solid consists of INTERNAL faces only.
|
||||
// Classification of any point relatively empty solid would always give IN status.
|
||||
// Thus, we consider all selected faces as IN without real classification.
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
myInFaces.Append(aVShapeBox(aIVec(k)).Shape());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare EF map of faces to process for building connexity blocks
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(1, anAlloc);
|
||||
if (aNbFP > 1)
|
||||
{
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
MapEdgesAndFaces(aVShapeBox(aIVec(k)).Shape(), aMEFP, anAlloc);
|
||||
}
|
||||
|
||||
// Map of Edge-Face connection, necessary for solid classification.
|
||||
// It will be filled when first classification is performed.
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFDS(1, anAlloc);
|
||||
|
||||
// Fence map to avoid processing of the same faces twice
|
||||
BOPCol_MapOfShape aMFDone(1, anAlloc);
|
||||
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
{
|
||||
Standard_Integer nFP = aIVec(k);
|
||||
const TopoDS_Face& aFP = (*(TopoDS_Face*)&aVShapeBox(nFP).Shape());
|
||||
if (!aMFDone.Add(aFP))
|
||||
continue;
|
||||
|
||||
// Make connexity blocks of faces, avoiding passing through the
|
||||
// borders of the solid. It helps to reduce significantly the
|
||||
// number of classified faces.
|
||||
BOPCol_ListOfShape aLCBF(anAlloc);
|
||||
// The most appropriate face for classification
|
||||
TopoDS_Face aFaceToClassify;
|
||||
MakeConnexityBlock(aFP, aMSE, aMEFP, aMFDone, aLCBF, aFaceToClassify);
|
||||
|
||||
if (!myBoxS.IsWhole())
|
||||
{
|
||||
// First, try fast classification of the whole block by additional
|
||||
// check on bounding boxes - check that bounding boxes of all vertices
|
||||
// of the block interfere with the box of the solid.
|
||||
// If not, the faces are out.
|
||||
Standard_Boolean bOut = Standard_False;
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More() && !bOut; aItLS.Next())
|
||||
{
|
||||
TopExp_Explorer anExpV(aItLS.Value(), TopAbs_VERTEX);
|
||||
for (; anExpV.More() && !bOut; anExpV.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aV = TopoDS::Vertex(anExpV.Current());
|
||||
Bnd_Box aBBV;
|
||||
aBBV.Add(BRep_Tool::Pnt(aV));
|
||||
aBBV.SetGap(BRep_Tool::Tolerance(aV));
|
||||
bOut = myBoxS.IsOut(aBBV);
|
||||
}
|
||||
}
|
||||
if (bOut)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aFaceToClassify.IsNull())
|
||||
aFaceToClassify = aFP;
|
||||
|
||||
if (aMEFDS.IsEmpty())
|
||||
// Fill EF map for Solid
|
||||
BOPTools::MapShapesAndAncestors(mySolid, TopAbs_EDGE, TopAbs_FACE, aMEFDS);
|
||||
|
||||
// All vertices are interfere with the solids box, run classification.
|
||||
Standard_Boolean bIsIN = BOPTools_AlgoTools::IsInternalFace
|
||||
(aFaceToClassify, mySolid, aMEFDS, Precision::Confusion(), myContext);
|
||||
if (bIsIN)
|
||||
{
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
myInFaces.Append(aItLS.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MapEdgesAndFaces(const TopoDS_Shape& theF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
myItF.Initialize(theF);
|
||||
for (; myItF.More(); myItF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aW = myItF.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next())
|
||||
{
|
||||
const TopoDS_Shape& aE = myItW.Value();
|
||||
|
||||
BOPCol_ListOfShape* pLF = theEFMap.ChangeSeek(aE);
|
||||
if (!pLF)
|
||||
pLF = &theEFMap(theEFMap.Add(aE, BOPCol_ListOfShape(theAllocator)));
|
||||
pLF->Append(theF);
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlock
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MakeConnexityBlock(const TopoDS_Face& theFStart,
|
||||
const BOPCol_IndexedMapOfShape& theMEAvoid,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
BOPCol_MapOfShape& theMFDone,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
TopoDS_Face& theFaceToClassify)
|
||||
{
|
||||
// Add start element
|
||||
theLCB.Append(theFStart);
|
||||
if (theEFMap.IsEmpty())
|
||||
return;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItCB(theLCB);
|
||||
for (; aItCB.More(); aItCB.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItCB.Value();
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aW = myItF.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next())
|
||||
{
|
||||
const TopoDS_Shape& aE = myItW.Value();
|
||||
if (theMEAvoid.Contains(aE))
|
||||
{
|
||||
if (theFaceToClassify.IsNull())
|
||||
theFaceToClassify = TopoDS::Face(aF);
|
||||
continue;
|
||||
}
|
||||
|
||||
const BOPCol_ListOfShape* pLF = theEFMap.Seek(aE);
|
||||
if (!pLF)
|
||||
continue;
|
||||
BOPCol_ListIteratorOfListOfShape aItLF(*pLF);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFToAdd = aItLF.Value();
|
||||
if (theMFDone.Add(aFToAdd))
|
||||
theLCB.Append(aFToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vector of solid classifiers
|
||||
typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> BOPAlgo_VectorOfFillIn3DParts;
|
||||
|
||||
// Functors to perform classification
|
||||
typedef BOPCol_ContextFunctor<BOPAlgo_FillIn3DParts,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPAlgo_FillIn3DPartsFunctor;
|
||||
|
||||
typedef BOPCol_ContextCnt<BOPAlgo_FillIn3DPartsFunctor,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
|
||||
|
||||
namespace {
|
||||
static void buildBoxForSolid (const TopoDS_Solid& theSolid,
|
||||
Bnd_Box& theBox)
|
||||
{
|
||||
Standard_Boolean bIsOpenBox = Standard_False;
|
||||
for (TopoDS_Iterator itS (theSolid); itS.More() && !bIsOpenBox; itS.Next())
|
||||
{
|
||||
const TopoDS_Shell& aShell = TopoDS::Shell (itS.Value());
|
||||
bIsOpenBox = BOPTools_AlgoTools::IsOpenShell (aShell);
|
||||
|
||||
if (bIsOpenBox)
|
||||
break;
|
||||
|
||||
for (TopoDS_Iterator itF (aShell); itF.More(); itF.Next())
|
||||
{
|
||||
const TopoDS_Face& aF = TopoDS::Face (itF.Value());
|
||||
|
||||
Bnd_Box aBoxF;
|
||||
BRepBndLib::Add (aF, aBoxF);
|
||||
|
||||
bIsOpenBox = (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
|
||||
aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
|
||||
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax());
|
||||
|
||||
if (bIsOpenBox)
|
||||
break;
|
||||
|
||||
theBox.Add (aBoxF);
|
||||
}
|
||||
}
|
||||
if (bIsOpenBox || BOPTools_AlgoTools::IsInvertedSolid (theSolid))
|
||||
theBox.SetWhole();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClassifyFaces
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_Tools::ClassifyFaces(const BOPCol_ListOfShape& theFaces,
|
||||
const BOPCol_ListOfShape& theSolids,
|
||||
const Standard_Boolean theRunParallel,
|
||||
Handle(IntTools_Context)& theContext,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
|
||||
const BOPCol_IndexedDataMapOfShapeBox* theBoxes,
|
||||
const BOPCol_DataMapOfShapeListOfShape* theSolidsIF)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Fill the vector of shape box with faces and its bounding boxes
|
||||
BOPAlgo_VectorOfShapeBox aVSB(256, anAlloc);
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLF(theFaces);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItLF.Value();
|
||||
// Append face to the vector of shape box
|
||||
BOPAlgo_ShapeBox& aSB = aVSB.Append1();
|
||||
aSB.SetShape(aF);
|
||||
|
||||
Bnd_Box aBox;
|
||||
if (theBoxes)
|
||||
{
|
||||
const Bnd_Box* pBox = theBoxes->Seek (aF);
|
||||
if (pBox)
|
||||
aBox = *pBox;
|
||||
}
|
||||
|
||||
if (aBox.IsVoid())
|
||||
{
|
||||
// Build the bounding box
|
||||
BRepBndLib::Add(aF, aBox);
|
||||
}
|
||||
aSB.SetBox(aBox);
|
||||
}
|
||||
|
||||
// Prepare UB tree of bounding boxes of the faces to classify
|
||||
// taking the bounding boxes from the just prepared vector
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Standard_Integer aNbF = aVSB.Length();
|
||||
for (Standard_Integer i = 0; i < aNbF; ++i)
|
||||
{
|
||||
aTreeFiller.Add(i, aVSB(i).Box());
|
||||
}
|
||||
|
||||
// Shake tree filler
|
||||
aTreeFiller.Fill();
|
||||
|
||||
// Prepare vector of solids to classify
|
||||
BOPAlgo_VectorOfFillIn3DParts aVFIP;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(theSolids);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Solid& aSolid = TopoDS::Solid(aItLS.Value());
|
||||
|
||||
// Build the bounding box for the solid
|
||||
Bnd_Box aBox;
|
||||
if (theBoxes)
|
||||
{
|
||||
const Bnd_Box* pBox = theBoxes->Seek (aSolid);
|
||||
if (pBox)
|
||||
aBox = *pBox;
|
||||
}
|
||||
if (aBox.IsVoid())
|
||||
{
|
||||
buildBoxForSolid (aSolid, aBox);
|
||||
}
|
||||
|
||||
// Append solid to the vector
|
||||
BOPAlgo_FillIn3DParts& aFIP = aVFIP.Append1();
|
||||
aFIP.SetSolid(aSolid);
|
||||
aFIP.SetBoxS(aBox);
|
||||
|
||||
if (theSolidsIF)
|
||||
{
|
||||
const BOPCol_ListOfShape* pLIF = theSolidsIF->Seek(aSolid);
|
||||
if (pLIF)
|
||||
aFIP.SetOwnIF(*pLIF);
|
||||
}
|
||||
|
||||
aFIP.SetBBTree(aBBTree);
|
||||
aFIP.SetShapeBoxVector(aVSB);
|
||||
}
|
||||
|
||||
// Perform classification
|
||||
//================================================================
|
||||
BOPAlgo_FillIn3DPartsCnt::Perform(theRunParallel, aVFIP, theContext);
|
||||
//================================================================
|
||||
|
||||
// Analyze the results and fill the resulting map
|
||||
|
||||
Standard_Integer aNbS = aVFIP.Length();
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
BOPAlgo_FillIn3DParts& aFIP = aVFIP(i);
|
||||
const TopoDS_Shape& aS = aFIP.Solid();
|
||||
const BOPCol_ListOfShape& aLFIn = aFIP.InFaces();
|
||||
theInParts.Add(aS, aLFIn);
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,9 @@
|
||||
|
||||
#include <BOPCol_BaseAllocator.hxx>
|
||||
#include <BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx>
|
||||
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeReal.hxx>
|
||||
#include <BOPCol_ListOfListOfShape.hxx>
|
||||
#include <BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx>
|
||||
@@ -155,6 +158,27 @@ public:
|
||||
const Standard_Real theFuzzyValue,
|
||||
BOPCol_ListOfListOfShape& theChains);
|
||||
|
||||
//! Classifies the faces <theFaces> relatively solids <theSolids>.
|
||||
//! The IN faces for solids are stored into output data map <theInParts>.
|
||||
//!
|
||||
//! The map <theSolidsIF> contains INTERNAL faces of the solids, to avoid
|
||||
//! their additional classification.
|
||||
//!
|
||||
//! Firstly, it checks the intersection of bounding boxes of the shapes.
|
||||
//! If the Box is not stored in the <theShapeBoxMap> map, it builds the box.
|
||||
//! If the bounding boxes of solid and face are interfering the classification is performed.
|
||||
//!
|
||||
//! It is assumed that all faces and solids are already intersected and
|
||||
//! do not have any geometrically coinciding parts without topological
|
||||
//! sharing of these parts
|
||||
Standard_EXPORT static void ClassifyFaces(const BOPCol_ListOfShape& theFaces,
|
||||
const BOPCol_ListOfShape& theSolids,
|
||||
const Standard_Boolean theRunParallel,
|
||||
Handle(IntTools_Context)& theContext,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
|
||||
const BOPCol_IndexedDataMapOfShapeBox* theBoxes = 0,
|
||||
const BOPCol_DataMapOfShapeListOfShape* theSolidsIF = 0);
|
||||
|
||||
};
|
||||
|
||||
#endif // _BOPAlgo_Tools_HeaderFile
|
||||
|
@@ -994,46 +994,61 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
|
||||
Handle(IntTools_Context)& theContext,
|
||||
const Standard_Real theFuzz)
|
||||
{
|
||||
Standard_Boolean bFlag;
|
||||
Standard_Integer iErr;
|
||||
Standard_Real aTolF1, aTolF2, aTol;
|
||||
gp_Pnt2d aP2D;
|
||||
gp_Pnt aP;
|
||||
TopoDS_Face aF1, aF2;
|
||||
TopoDS_Edge aE1;
|
||||
TopExp_Explorer aExp;
|
||||
Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
|
||||
//
|
||||
bFlag=Standard_False;
|
||||
//
|
||||
aF1=theF1;
|
||||
aF1.Orientation(TopAbs_FORWARD);
|
||||
aF2=theF2;
|
||||
aF2.Orientation(TopAbs_FORWARD);
|
||||
//
|
||||
aTolF1=BRep_Tool::Tolerance(aF1);
|
||||
// 1
|
||||
aExp.Init(aF1, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
aE1=(*(TopoDS_Edge*)(&aExp.Current()));
|
||||
if (!BRep_Tool::Degenerated(aE1)) {
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
|
||||
if (aTolE > aTolF1) {
|
||||
aTolF1 = aTolE;
|
||||
Standard_Boolean bFacesSD = Standard_False;
|
||||
|
||||
// The idea is to find a point inside the first face
|
||||
// and check its validity for the second face.
|
||||
// If valid - the faces are same domain.
|
||||
|
||||
gp_Pnt aP1;
|
||||
gp_Pnt2d aP2D1;
|
||||
// Find point inside the first face
|
||||
Standard_Integer iErr =
|
||||
BOPTools_AlgoTools3D::PointInFace(theF1, aP1, aP2D1, theContext);
|
||||
|
||||
if (iErr != 0)
|
||||
{
|
||||
// unable to find the point
|
||||
return bFacesSD;
|
||||
}
|
||||
|
||||
// Check validity of the point for second face
|
||||
|
||||
// Compute the tolerance to check the validity -
|
||||
// sum of tolerance of faces and fuzzy tolerance
|
||||
|
||||
// Compute the tolerance of the faces, taking into account the deviation
|
||||
// of the edges from the surfaces
|
||||
Standard_Real aTolF1 = BRep_Tool::Tolerance(theF1),
|
||||
aTolF2 = BRep_Tool::Tolerance(theF2);
|
||||
|
||||
// Find maximal tolerance of edges.
|
||||
// The faces should have the same boundaries, thus
|
||||
// it does not matter which face to explore.
|
||||
{
|
||||
Standard_Real aTolEMax = -1.;
|
||||
TopExp_Explorer anExpE(theF1, TopAbs_EDGE);
|
||||
for (; anExpE.More(); anExpE.Next())
|
||||
{
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
|
||||
if (!BRep_Tool::Degenerated(aE))
|
||||
{
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
|
||||
if (aTolE > aTolEMax)
|
||||
aTolEMax = aTolE;
|
||||
}
|
||||
}
|
||||
if (aTolEMax > aTolF1) aTolF1 = aTolEMax;
|
||||
if (aTolEMax > aTolF2) aTolF2 = aTolEMax;
|
||||
}
|
||||
// 2
|
||||
aTolF2=BRep_Tool::Tolerance(aF2);
|
||||
aTol = aTolF1 + aTolF2 + aFuzz1;
|
||||
//
|
||||
iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
|
||||
theContext);
|
||||
if (!iErr) {
|
||||
bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
|
||||
}
|
||||
//
|
||||
return bFlag;
|
||||
|
||||
// Checking criteria
|
||||
Standard_Real aTol = aTolF1 + aTolF2 + Max(theFuzz, Precision::Confusion());
|
||||
|
||||
// Project and classify the point on second face
|
||||
bFacesSD = theContext->IsValidPointForFace(aP1, theF2, aTol);
|
||||
|
||||
return bFacesSD;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -144,13 +144,6 @@ BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
|
||||
|
||||
TFirst = 0;
|
||||
TLast = myKnots->Value(myKnots->Length());
|
||||
myPeriod = TLast - TFirst;
|
||||
if (NbEdge == 1) {
|
||||
Periodic = myCurves->Value(1).IsPeriodic();
|
||||
}
|
||||
else {
|
||||
Periodic = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
void BRepAdaptor_CompCurve::Initialize(const TopoDS_Wire& W,
|
||||
@@ -200,15 +193,6 @@ BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BRepAdaptor_CompCurve::SetPeriodic(const Standard_Boolean isPeriodic)
|
||||
{
|
||||
if (myWire.Closed()) {
|
||||
Periodic = isPeriodic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
{
|
||||
return myWire;
|
||||
@@ -308,13 +292,13 @@ const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
|
||||
Standard_Boolean BRepAdaptor_CompCurve::IsPeriodic() const
|
||||
{
|
||||
return Periodic;
|
||||
return Standard_False;
|
||||
|
||||
}
|
||||
|
||||
Standard_Real BRepAdaptor_CompCurve::Period() const
|
||||
{
|
||||
return myPeriod;
|
||||
return (TLast - TFirst);
|
||||
}
|
||||
|
||||
gp_Pnt BRepAdaptor_CompCurve::Value(const Standard_Real U) const
|
||||
@@ -475,12 +459,6 @@ const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
|
||||
|
||||
Wtest = W+Eps; //Offset to discriminate the nodes
|
||||
if(Periodic){
|
||||
Wtest = ElCLib::InPeriod(Wtest,
|
||||
0,
|
||||
myPeriod);
|
||||
W = Wtest-Eps;
|
||||
}
|
||||
|
||||
// Find the index
|
||||
Standard_Boolean Trouve = Standard_False;
|
||||
|
@@ -52,7 +52,13 @@ class Geom_BSplineCurve;
|
||||
//! The Curve from BRepAdaptor allows to use a Wire
|
||||
//! of the BRep topology like a 3D curve.
|
||||
//! Warning: With this class of curve, C0 and C1 continuities
|
||||
//! are not assumed. So be carful with some algorithm!
|
||||
//! are not assumed. So be careful with some algorithm!
|
||||
//! Please note that BRepAdaptor_CompCurve cannot be
|
||||
//! periodic curve at all (even if it contains single
|
||||
//! periodic edge).
|
||||
//!
|
||||
//! BRepAdaptor_CompCurve can only work on valid wires where all edges are
|
||||
//! connected to each other to make a chain.
|
||||
class BRepAdaptor_CompCurve : public Adaptor3d_Curve
|
||||
{
|
||||
public:
|
||||
@@ -75,10 +81,6 @@ public:
|
||||
//! Sets wire <W> and trimmed parameter.
|
||||
Standard_EXPORT void Initialize (const TopoDS_Wire& W, const Standard_Boolean KnotByCurvilinearAbcissa, const Standard_Real First, const Standard_Real Last, const Standard_Real Tol);
|
||||
|
||||
//! Set the flag Periodic.
|
||||
//! Warning: This method has no effect if the wire is not closed
|
||||
Standard_EXPORT void SetPeriodic (const Standard_Boolean Periodic);
|
||||
|
||||
//! Returns the wire.
|
||||
Standard_EXPORT const TopoDS_Wire& Wire() const;
|
||||
|
||||
|
@@ -115,8 +115,9 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
|
||||
}
|
||||
else {
|
||||
for (;ex2.More();ex2.Next()) {
|
||||
BC.Initialize(TopoDS::Edge(ex2.Current()));
|
||||
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(F), B);
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(ex2.Current());
|
||||
BC.Initialize(anEdge);
|
||||
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(anEdge), B);
|
||||
}
|
||||
B.Enlarge(BRep_Tool::Tolerance(F));
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
static const Standard_Real Probing_Start = 0.123;
|
||||
static const Standard_Real Probing_End = 0.7;
|
||||
@@ -41,27 +42,28 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
|
||||
myFace(F),
|
||||
myCurEdgeInd(1),
|
||||
myCurEdgePar(Probing_Start)
|
||||
{
|
||||
{
|
||||
myFace.Orientation(TopAbs_FORWARD);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckPoint
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
|
||||
Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
|
||||
{
|
||||
Standard_Real anUMin = 0.0, anUMax = 0.0, aVMin = 0.0, aVMax = 0.0;
|
||||
TopLoc_Location aLocation;
|
||||
const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(myFace, aLocation);
|
||||
aSurface->Bounds(anUMin, anUMax, aVMin, aVMax);
|
||||
if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
|
||||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
|
||||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
|
||||
{
|
||||
BRepTools::UVBounds(myFace, anUMin, anUMax, aVMin, aVMax);
|
||||
if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
|
||||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
|
||||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -71,14 +73,14 @@ Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
|
||||
Standard_Real aDistance = aCenterPnt.Distance(thePoint);
|
||||
if (Precision::IsInfinite(aDistance))
|
||||
{
|
||||
thePoint.SetCoord(anUMin - ( anUMax - anUMin ),
|
||||
aVMin - ( aVMax - aVMin ));
|
||||
thePoint.SetCoord (anUMin - (anUMax - anUMin ),
|
||||
aVMin - (aVMax - aVMin ));
|
||||
return Standard_False;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real anEpsilon = Epsilon(aDistance);
|
||||
if (anEpsilon > Max(anUMax - anUMin, aVMax - aVMin))
|
||||
if (anEpsilon > Max (anUMax - anUMin, aVMax - aVMin))
|
||||
{
|
||||
gp_Vec2d aLinVec(aCenterPnt, thePoint);
|
||||
gp_Dir2d aLinDir(aLinVec);
|
||||
@@ -124,7 +126,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
gp_Lin2d& L,
|
||||
Standard_Real& Par)
|
||||
{
|
||||
TopExp_Explorer anExpF(myFace,TopAbs_EDGE);
|
||||
TopExp_Explorer anExpF(myFace, TopAbs_EDGE);
|
||||
Standard_Integer i;
|
||||
Standard_Real aFPar;
|
||||
Standard_Real aLPar;
|
||||
@@ -137,7 +139,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
if (i != myCurEdgeInd)
|
||||
continue;
|
||||
|
||||
const TopoDS_Shape &aLocalShape = anExpF.Current();
|
||||
const TopoDS_Shape &aLocalShape = anExpF.Current();
|
||||
const TopAbs_Orientation anOrientation = aLocalShape.Orientation();
|
||||
|
||||
if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
|
||||
@@ -146,27 +148,29 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
|
||||
|
||||
if (!aC2d.IsNull()) {
|
||||
// Treatment of infinite cases.
|
||||
if (Precision::IsNegativeInfinite(aFPar)) {
|
||||
if (Precision::IsPositiveInfinite(aLPar)) {
|
||||
aFPar = -1.;
|
||||
aLPar = 1.;
|
||||
} else {
|
||||
aFPar = aLPar - 1.;
|
||||
}
|
||||
} else if (Precision::IsPositiveInfinite(aLPar))
|
||||
aLPar = aFPar + 1.;
|
||||
// Treatment of infinite cases.
|
||||
if (Precision::IsNegativeInfinite(aFPar)) {
|
||||
if (Precision::IsPositiveInfinite(aLPar)) {
|
||||
aFPar = -1.;
|
||||
aLPar = 1.;
|
||||
}
|
||||
else {
|
||||
aFPar = aLPar - 1.;
|
||||
}
|
||||
}
|
||||
else if (Precision::IsPositiveInfinite(aLPar))
|
||||
aLPar = aFPar + 1.;
|
||||
|
||||
for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
|
||||
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
|
||||
for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) {
|
||||
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
|
||||
|
||||
gp_Vec2d aTanVec;
|
||||
aC2d->D1(aParamIn, aPOnC, aTanVec);
|
||||
Par = aPOnC.SquareDistance(P);
|
||||
aC2d->D1(aParamIn, aPOnC, aTanVec);
|
||||
Par = aPOnC.SquareDistance(P);
|
||||
|
||||
if (Par > aTolParConf2) {
|
||||
gp_Vec2d aLinVec(P, aPOnC);
|
||||
gp_Dir2d aLinDir(aLinVec);
|
||||
if (Par > aTolParConf2) {
|
||||
gp_Vec2d aLinVec(P, aPOnC);
|
||||
gp_Dir2d aLinDir(aLinVec);
|
||||
|
||||
Standard_Real aTanMod = aTanVec.SquareMagnitude();
|
||||
if (aTanMod < aTolParConf2)
|
||||
@@ -174,8 +178,10 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
aTanVec /= Sqrt(aTanMod);
|
||||
Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
|
||||
const Standard_Real SmallAngle = 0.001;
|
||||
Standard_Boolean isSmallAngle = Standard_False;
|
||||
if (Abs(aSinA) < SmallAngle)
|
||||
{
|
||||
isSmallAngle = Standard_True;
|
||||
// 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
|
||||
@@ -185,28 +191,62 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
continue;
|
||||
}
|
||||
|
||||
L = gp_Lin2d(P, aLinDir);
|
||||
L = gp_Lin2d(P, aLinDir);
|
||||
|
||||
// Check if ends of a curve lie on a line.
|
||||
aC2d->D0(aFPar, aPOnC);
|
||||
// Check if ends of a curve lie on a line.
|
||||
aC2d->D0(aFPar, aPOnC);
|
||||
Standard_Real aFDist = P.SquareDistance(aPOnC);
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
aC2d->D0(aLPar, aPOnC);
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
Standard_Real aLDist = P.SquareDistance(aPOnC);
|
||||
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
aC2d->D0(aLPar, aPOnC);
|
||||
if (isSmallAngle)
|
||||
{
|
||||
//Try to find minimal distance between curve and line
|
||||
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
myCurEdgePar += Probing_Step;
|
||||
Geom2dAPI_ProjectPointOnCurve aProj;
|
||||
aProj.Init(P, aC2d, aFPar, aLPar);
|
||||
if (aProj.NbPoints() > 0)
|
||||
{
|
||||
Standard_Real aMinDist = aProj.LowerDistance();
|
||||
aMinDist *= aMinDist;
|
||||
Standard_Real aTMin = aProj.LowerDistanceParameter();
|
||||
if (aMinDist > aFDist)
|
||||
{
|
||||
aMinDist = aFDist;
|
||||
aTMin = aFPar;
|
||||
}
|
||||
if (aMinDist > aLDist)
|
||||
{
|
||||
aMinDist = aLDist;
|
||||
aTMin = aLPar;
|
||||
}
|
||||
if (aMinDist < Par)
|
||||
{
|
||||
Par = aMinDist;
|
||||
if (Par < aTolParConf2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
aC2d->D1(aTMin, aPOnC, aTanVec);
|
||||
aLinDir.SetXY(aTanVec.XY());
|
||||
L = gp_Lin2d(P, aLinDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
myCurEdgePar += Probing_Step;
|
||||
if (myCurEdgePar >= Probing_End) {
|
||||
myCurEdgeInd++;
|
||||
myCurEdgePar = Probing_Start;
|
||||
}
|
||||
|
||||
if (myCurEdgePar >= Probing_End) {
|
||||
myCurEdgeInd++;
|
||||
myCurEdgePar = Probing_Start;
|
||||
}
|
||||
|
||||
Par = Sqrt(Par);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Par = Sqrt(Par);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if (!aC2d.IsNull()) {
|
||||
} // if (anOrientation == TopAbs_FORWARD ...
|
||||
|
||||
@@ -217,7 +257,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
|
||||
// nothing found, return an horizontal line
|
||||
Par = RealLast();
|
||||
L = gp_Lin2d(P,gp_Dir2d(1,0));
|
||||
L = gp_Lin2d(P, gp_Dir2d(1, 0));
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
@@ -135,10 +135,10 @@ void BRepClass_Intersector::Perform(const gp_Lin2d& L,
|
||||
IntRes2d_Domain DL;
|
||||
//
|
||||
if(P!=RealLast()) {
|
||||
DL.SetValues(L.Location(),0.,aTolZ,ElCLib::Value(P,L),P,aTolZ);
|
||||
DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
|
||||
}
|
||||
else {
|
||||
DL.SetValues(L.Location(),0.,aTolZ,Standard_True);
|
||||
DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
|
||||
}
|
||||
|
||||
IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
|
||||
|
@@ -385,10 +385,8 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
|
||||
if (Affich)
|
||||
DBRep::Set("theguide", TheGuide);
|
||||
#endif
|
||||
// transform the guide in a single curve (periodic if posssible)
|
||||
Handle(BRepAdaptor_HCompCurve) Guide =
|
||||
new (BRepAdaptor_HCompCurve) (TheGuide);
|
||||
Guide->ChangeCurve().SetPeriodic(Standard_True);
|
||||
// transform the guide in a single curve
|
||||
Handle(BRepAdaptor_HCompCurve) Guide = new (BRepAdaptor_HCompCurve) (TheGuide);
|
||||
|
||||
if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
|
||||
if (KeepContact == BRepFill_Contact ||
|
||||
|
@@ -131,10 +131,10 @@ BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W,
|
||||
|
||||
void BRepLib_MakeWire::Add(const TopoDS_Wire& W)
|
||||
{
|
||||
TopExp_Explorer ex(W,TopAbs_EDGE);
|
||||
while (ex.More()) {
|
||||
Add(TopoDS::Edge(ex.Current()));
|
||||
ex.Next();
|
||||
for (TopoDS_Iterator it(W); it.More(); it.Next()) {
|
||||
Add(TopoDS::Edge(it.Value()));
|
||||
if (myError != BRepLib_WireDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <BRepLib_WireError.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <BRepLib_MakeShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
@@ -172,14 +173,14 @@ private:
|
||||
};
|
||||
|
||||
void CollectCoincidentVertices(const TopTools_ListOfShape& theL,
|
||||
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL);
|
||||
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL);
|
||||
|
||||
void CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV);
|
||||
TopTools_DataMapOfShapeShape& theO2NV);
|
||||
|
||||
void CreateNewListOfEdges(const TopTools_ListOfShape& theL,
|
||||
const NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV,
|
||||
TopTools_ListOfShape& theNewEList);
|
||||
const TopTools_DataMapOfShapeShape& theO2NV,
|
||||
TopTools_ListOfShape& theNewEList);
|
||||
|
||||
void Add(const TopoDS_Edge& E, Standard_Boolean IsCheckGeometryProximity);
|
||||
|
||||
|
@@ -58,7 +58,7 @@ void BRepLib_MakeWire::Add(const TopTools_ListOfShape& L)
|
||||
|
||||
CollectCoincidentVertices(L, aGrVL);
|
||||
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex> anO2NV;
|
||||
TopTools_DataMapOfShapeShape anO2NV;
|
||||
|
||||
CreateNewVertices(aGrVL, anO2NV);
|
||||
|
||||
@@ -155,8 +155,10 @@ Standard_Boolean BRepLib_MakeWire::BRepLib_BndBoxVertexSelector::
|
||||
Standard_Real aTolV = BRep_Tool::Tolerance(aV);
|
||||
|
||||
Standard_Real aL = myP.SquareDistance(aVPnt);
|
||||
Standard_Real aTol = aTolV + mySTol;
|
||||
aTol *= aTol;
|
||||
|
||||
if (aL < Max(aTolV*aTolV, mySTol))
|
||||
if (aL <= aTol)
|
||||
{
|
||||
myResultInd.Append(theObj);
|
||||
return Standard_True;
|
||||
@@ -176,7 +178,7 @@ void BRepLib_MakeWire::BRepLib_BndBoxVertexSelector::
|
||||
myP = theP;
|
||||
myVBox.Add(myP);
|
||||
myVBox.Enlarge(theTol);
|
||||
mySTol = theTol*theTol;
|
||||
mySTol = theTol;
|
||||
myVInd = theVInd;
|
||||
}
|
||||
|
||||
@@ -188,17 +190,13 @@ void BRepLib_MakeWire::CollectCoincidentVertices(const TopTools_ListOfShape& the
|
||||
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL)
|
||||
{
|
||||
TopTools_IndexedMapOfShape anAllV;
|
||||
TopTools_ListIteratorOfListOfShape anItL;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMV2EL;
|
||||
|
||||
TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMV2EL);
|
||||
TopExp_Explorer exp;
|
||||
for (anItL.Initialize(theL); anItL.More(); anItL.Next())
|
||||
TopExp::MapShapesAndAncestors(anItL.Value(), TopAbs_VERTEX, TopAbs_EDGE, aMV2EL);
|
||||
TopExp::MapShapes(myShape, TopAbs_VERTEX, anAllV);
|
||||
|
||||
for (int i = 1; i <= aMV2EL.Extent(); i++)
|
||||
if (aMV2EL(i).Extent() == 1)
|
||||
anAllV.Add(aMV2EL.FindKey(i));
|
||||
TopTools_ListIteratorOfListOfShape anItL(theL);
|
||||
for (; anItL.More(); anItL.Next())
|
||||
TopExp::MapShapes(anItL.Value(), TopAbs_VERTEX, anAllV);
|
||||
|
||||
//aV2CV : vertex <-> its coincident vertices
|
||||
NCollection_DataMap<TopoDS_Vertex, NCollection_Map<TopoDS_Vertex>> aV2CV;
|
||||
@@ -303,8 +301,8 @@ void BRepLib_MakeWire::CollectCoincidentVertices(const TopTools_ListOfShape& the
|
||||
//function : CreateNewVertices
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV)
|
||||
void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
|
||||
TopTools_DataMapOfShapeShape& theO2NV)
|
||||
{
|
||||
//map [old vertex => new vertex]
|
||||
//note that already existing shape (i.e. the original ones)
|
||||
@@ -356,7 +354,7 @@ void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepLib_MakeWire::CreateNewListOfEdges(const TopTools_ListOfShape& theL,
|
||||
const NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV,
|
||||
const TopTools_DataMapOfShapeShape& theO2NV,
|
||||
TopTools_ListOfShape& theNewEList)
|
||||
{
|
||||
///create the new list (theNewEList) from the input list L
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <BRepMesh_Vertex.hxx>
|
||||
#include <BRepMesh_Triangle.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -304,6 +305,17 @@ void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes)
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly)
|
||||
{
|
||||
createTriangles (theVertexIndex, thePoly, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createTriangles
|
||||
//purpose : Creates the triangles beetween the node and the polyline.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
BRepMesh::ListOfInteger aLoopEdges, anExternalEdges;
|
||||
const gp_XY& aVertexCoord = myMeshData->GetNode( theVertexIndex ).Coord();
|
||||
@@ -311,6 +323,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
BRepMesh::MapOfIntegerInteger::Iterator anEdges( thePoly );
|
||||
for ( ; anEdges.More(); anEdges.Next() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Standard_Integer anEdgeId = anEdges.Key();
|
||||
const BRepMesh_Edge& anEdge = GetEdge( anEdgeId );
|
||||
|
||||
@@ -408,6 +424,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
|
||||
while ( !aLoopEdges.IsEmpty() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const BRepMesh_Edge& anEdge = GetEdge( Abs( aLoopEdges.First() ) );
|
||||
if ( anEdge.Movability() != BRepMesh_Deleted )
|
||||
{
|
||||
@@ -425,6 +445,17 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
BRepMesh::Array1OfInteger& theVertexIndexes)
|
||||
{
|
||||
createTrianglesOnNewVertices (theVertexIndexes, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createTrianglesOnNewVertices
|
||||
//purpose : Creation of triangles from the new nodes
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
BRepMesh::Array1OfInteger& theVertexIndexes,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Handle(NCollection_IncAllocator) aAllocator =
|
||||
new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
|
||||
@@ -440,6 +471,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
Standard_Integer anUpper = theVertexIndexes.Upper();
|
||||
for( ; anIndex <= anUpper; ++anIndex )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
aAllocator->Reset(Standard_False);
|
||||
BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
|
||||
|
||||
@@ -483,6 +519,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
isModify = Standard_True;
|
||||
while ( isModify && !aCirclesList.IsEmpty() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isModify = Standard_False;
|
||||
BRepMesh::ListOfInteger::Iterator aCircleIt1( aCirclesList );
|
||||
for ( ; aCircleIt1.More(); aCircleIt1.Next() )
|
||||
@@ -503,13 +544,25 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
}
|
||||
}
|
||||
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Creation of triangles with the current node and free edges
|
||||
// and removal of these edges from the list of free edges
|
||||
createTriangles( aVertexIdx, aLoopEdges );
|
||||
createTriangles( aVertexIdx, aLoopEdges, theProgressEntry );
|
||||
}
|
||||
}
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
insertInternalEdges();
|
||||
insertInternalEdges (theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjustment of meshes to boundary edges
|
||||
frontierAdjust();
|
||||
@@ -520,6 +573,15 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::insertInternalEdges()
|
||||
{
|
||||
insertInternalEdges (NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : insertInternalEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::insertInternalEdges (Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
BRepMesh::HMapOfInteger anInternalEdges = InternalEdges();
|
||||
|
||||
@@ -530,6 +592,11 @@ void BRepMesh_Delaun::insertInternalEdges()
|
||||
BRepMesh::MapOfInteger::Iterator anInernalEdgesIt( *anInternalEdges );
|
||||
for ( ; anInernalEdgesIt.More(); anInernalEdgesIt.Next() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aLinkIndex = anInernalEdgesIt.Key();
|
||||
const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(aLinkIndex);
|
||||
|
||||
@@ -2094,12 +2161,21 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertices
|
||||
//purpose : Adds some vertices in the triangulation.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices)
|
||||
{
|
||||
AddVertices (theVertices, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertices
|
||||
//purpose : Adds some vertices in the triangulation.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
std::make_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
|
||||
std::sort_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
|
||||
@@ -2111,7 +2187,7 @@ void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices)
|
||||
for ( Standard_Integer i = aLower; i <= anUpper; ++i )
|
||||
aVertexIndexes(i) = myMeshData->AddNode( theVertices(i) );
|
||||
|
||||
createTrianglesOnNewVertices( aVertexIndexes );
|
||||
createTrianglesOnNewVertices( aVertexIndexes, theProgressEntry );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -33,6 +33,7 @@
|
||||
class Bnd_B2d;
|
||||
class Bnd_Box2d;
|
||||
class BRepMesh_Vertex;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Compute the Delaunay's triangulation with the algorithm of Watson.
|
||||
class BRepMesh_Delaun
|
||||
@@ -61,6 +62,10 @@ public:
|
||||
//! Adds some vertices into the triangulation.
|
||||
Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices);
|
||||
|
||||
//! Adds some vertices into the triangulation.
|
||||
Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Modify mesh to use the edge.
|
||||
//! @return True if done
|
||||
Standard_EXPORT Standard_Boolean UseEdge (const Standard_Integer theEdge);
|
||||
@@ -222,6 +227,10 @@ private:
|
||||
void createTriangles (const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly);
|
||||
|
||||
void createTriangles (const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Add a triangle based on the given oriented edges into mesh
|
||||
void addTriangle (const Standard_Integer (&theEdgesId)[3],
|
||||
const Standard_Boolean (&theEdgesOri)[3],
|
||||
@@ -252,6 +261,10 @@ private:
|
||||
BRepMesh::SequenceOfInteger& thePolygon,
|
||||
BRepMesh::SequenceOfBndB2d& thePolyBoxes);
|
||||
|
||||
//! Creates the triangles on new nodes.
|
||||
void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Creates the triangles on new nodes.
|
||||
void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices);
|
||||
|
||||
@@ -323,6 +336,9 @@ private:
|
||||
//! Performs insertion of internal edges into mesh.
|
||||
void insertInternalEdges();
|
||||
|
||||
//! Performs insertion of internal edges into mesh.
|
||||
void insertInternalEdges (Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
private:
|
||||
|
||||
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
|
||||
#include <BRep_PointRepresentation.hxx>
|
||||
|
||||
@@ -123,15 +124,25 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
|
||||
OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Process
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
|
||||
{
|
||||
Process (theFace, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Process
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscret::Process (const TopoDS_Face& theFace,
|
||||
Message_ProgressSentry* theProgrEntry) const
|
||||
{
|
||||
Handle(BRepMesh_FaceAttribute) anAttribute;
|
||||
if (GetFaceAttribute(theFace, anAttribute))
|
||||
if (GetFaceAttribute(theFace, anAttribute)
|
||||
&& (theProgrEntry == NULL || theProgrEntry->More()))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -139,7 +150,7 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
|
||||
|
||||
BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize,
|
||||
myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
|
||||
aTool.Perform(anAttribute);
|
||||
aTool.Perform (anAttribute, theProgrEntry);
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
|
@@ -46,6 +46,7 @@ class BRepMesh_Edge;
|
||||
class BRepMesh_Vertex;
|
||||
class gp_Pnt;
|
||||
class BRepMesh_FaceAttribute;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Algorithm to mesh a shape with respect of the <br>
|
||||
//! frontier the deflection and by option the shared <br>
|
||||
@@ -129,6 +130,12 @@ public:
|
||||
//! parallel threads.
|
||||
Standard_EXPORT void Process(const TopoDS_Face& face) const;
|
||||
|
||||
//! Triangulate a face previously recorded for
|
||||
//! processing by call to Add(). Can be executed in
|
||||
//! parallel threads.
|
||||
Standard_EXPORT void Process (const TopoDS_Face& theFace,
|
||||
Message_ProgressSentry* theProgrEntry) const;
|
||||
|
||||
void operator () (const TopoDS_Face& face) const
|
||||
{
|
||||
Process(face);
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <Bnd_Box2d.hxx>
|
||||
|
||||
@@ -187,7 +188,21 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace(
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute)
|
||||
{
|
||||
add(theAttribute);
|
||||
Perform (theAttribute, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
add(theAttribute, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
commitSurfaceTriangulation();
|
||||
}
|
||||
|
||||
@@ -345,7 +360,8 @@ void BRepMesh_FastDiscretFace::addLinkToMesh(
|
||||
//function : Add
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttribute)
|
||||
void BRepMesh_FastDiscretFace::add (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
if (!theAttribute->IsValid() || theAttribute->ChangeMeshNodes()->IsEmpty())
|
||||
return;
|
||||
@@ -397,12 +413,22 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
(vmax - vmin) < Precision::PConfusion());
|
||||
|
||||
Standard_Real aDef = -1;
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
|
||||
{
|
||||
if (!rajout)
|
||||
{
|
||||
// compute maximal deflection
|
||||
aDef = control(trigu, Standard_True);
|
||||
aDef = control(trigu, Standard_True, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.);
|
||||
}
|
||||
if (thetype != GeomAbs_Plane)
|
||||
@@ -415,11 +441,21 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
|
||||
if (rajout)
|
||||
{
|
||||
insertInternalVertices(trigu);
|
||||
insertInternalVertices(trigu, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//control internal points
|
||||
if (myIsControlSurfaceDeflection)
|
||||
aDef = control(trigu, Standard_False);
|
||||
{
|
||||
aDef = control(trigu, Standard_False, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,7 +483,8 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
|
||||
const BRepMesh::ListOfVertex& theVertices,
|
||||
BRepMesh_Delaun& theMeshBuilder)
|
||||
BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
if (theVertices.IsEmpty())
|
||||
return Standard_False;
|
||||
@@ -457,8 +494,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
|
||||
for (Standard_Integer aVertexId = 0; aVertexIt.More(); aVertexIt.Next())
|
||||
aArrayOfNewVertices(++aVertexId) = aVertexIt.Value();
|
||||
|
||||
theMeshBuilder.AddVertices(aArrayOfNewVertices);
|
||||
return Standard_True;
|
||||
theMeshBuilder.AddVertices(aArrayOfNewVertices, theProgressEntry);
|
||||
return theProgressEntry == NULL || theProgressEntry->More();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -527,7 +564,8 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
|
||||
//function : insertInternalVertices
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBuilder)
|
||||
void BRepMesh_FastDiscretFace::insertInternalVertices (BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
BRepMesh::ListOfVertex aNewVertices(anAlloc);
|
||||
@@ -555,7 +593,7 @@ void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBu
|
||||
break;
|
||||
}
|
||||
|
||||
addVerticesToMesh(aNewVertices, theMeshBuilder);
|
||||
addVerticesToMesh(aNewVertices, theMeshBuilder, theProgressEntry);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1182,7 +1220,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
|
||||
//=======================================================================
|
||||
Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
BRepMesh_Delaun& theTrigu,
|
||||
const Standard_Boolean theIsFirst)
|
||||
const Standard_Boolean theIsFirst,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent();
|
||||
if (aTrianglesNb < 1)
|
||||
@@ -1219,6 +1258,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
|
||||
for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
aTempAlloc->Reset(Standard_False);
|
||||
BRepMesh::ListOfVertex aNewVertices(aTempAlloc);
|
||||
|
||||
@@ -1236,6 +1280,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
BRepMesh::MapOfInteger::Iterator aTriangleIt(aTriangles);
|
||||
for (; aTriangleIt.More(); aTriangleIt.Next())
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Standard_Integer aTriangleId = aTriangleIt.Key();
|
||||
const BRepMesh_Triangle& aCurrentTriangle = myStructure->GetElement(aTriangleId);
|
||||
|
||||
@@ -1398,8 +1447,12 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
<< aP.X() << " " << aP.Y() << " " << aP.Z() << endl;
|
||||
}
|
||||
#endif
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addVerticesToMesh(aNewVertices, theTrigu))
|
||||
if (addVerticesToMesh(aNewVertices, theTrigu, theProgressEntry))
|
||||
++aInsertedNb;
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,7 @@ class gp_Pnt2d;
|
||||
class BRepMesh_Edge;
|
||||
class BRepMesh_Vertex;
|
||||
class gp_Pnt;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Algorithm to mesh a face with respect of the frontier
|
||||
//! the deflection and by option the shared components.
|
||||
@@ -62,15 +63,19 @@ public:
|
||||
|
||||
Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
|
||||
|
||||
Standard_EXPORT void Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
|
||||
|
||||
private:
|
||||
|
||||
void add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
|
||||
void add(const Handle(BRepMesh_FaceAttribute)& theAttribute, Message_ProgressSentry* theProgressEntry);
|
||||
void add(const TopoDS_Vertex& theVertex);
|
||||
|
||||
Standard_Real control(BRepMesh_Delaun& theMeshBuilder,
|
||||
const Standard_Boolean theIsFirst);
|
||||
const Standard_Boolean theIsFirst,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Registers the given nodes in mesh data structure and
|
||||
//! performs refinement of existing mesh.
|
||||
@@ -80,12 +85,14 @@ private:
|
||||
//! @return TRUE if vertices were been inserted, FALSE elewhere.
|
||||
Standard_Boolean addVerticesToMesh(
|
||||
const BRepMesh::ListOfVertex& theVertices,
|
||||
BRepMesh_Delaun& theMeshBuilder);
|
||||
BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Calculates nodes lying on face's surface and inserts them to a mesh.
|
||||
//! @param theMeshBuilder initialized tool refining mesh
|
||||
//! in respect to inserting nodes.
|
||||
void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder);
|
||||
void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Calculates nodes lying on spherical surface.
|
||||
//! @param theNewVertices list of vertices to be extended and added to mesh.
|
||||
|
@@ -54,6 +54,8 @@
|
||||
|
||||
#include <GCPnts_TangentialDeflection.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
|
||||
|
||||
namespace
|
||||
@@ -63,6 +65,51 @@ namespace
|
||||
static Standard_Boolean IS_IN_PARALLEL = Standard_False;
|
||||
}
|
||||
|
||||
class BRepMesh_IncrementalMesh::FaceListFunctor
|
||||
{
|
||||
public:
|
||||
FaceListFunctor (BRepMesh_IncrementalMesh* theAlgo,
|
||||
const Handle(Message_ProgressIndicator)& theProgress,
|
||||
Standard_Boolean theParallel)
|
||||
: myAlgo (theAlgo),
|
||||
mySentry (theProgress, "Mesh faces", 0, theAlgo->myFaces.Size(), 1),
|
||||
myThreadId (OSD_Thread::Current()),
|
||||
myIsParallel (theParallel),
|
||||
myHasProgress (!theProgress.IsNull())
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (const Standard_Integer theFaceIndex) const
|
||||
{
|
||||
if (!mySentry.More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TopoDS_Face& aFace = myAlgo->myFaces.ChangeValue (theFaceIndex);
|
||||
myAlgo->myMesh->Process (aFace, &mySentry);
|
||||
|
||||
if (myIsParallel)
|
||||
{
|
||||
// use a trick to avoid mutex locks - increment the progress only within main thread
|
||||
if (myHasProgress && myThreadId == OSD_Thread::Current())
|
||||
{
|
||||
mySentry.Next (OSD_Parallel::NbLogicalProcessors());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mySentry.Next();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable BRepMesh_IncrementalMesh* myAlgo;
|
||||
mutable Message_ProgressSentry mySentry;
|
||||
Standard_ThreadId myThreadId;
|
||||
Standard_Boolean myIsParallel;
|
||||
Standard_Boolean myHasProgress;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : Default constructor
|
||||
@@ -202,41 +249,94 @@ void BRepMesh_IncrementalMesh::collectFaces()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::Perform()
|
||||
{
|
||||
Perform (Handle(Message_ProgressIndicator)());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::Perform (const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
init();
|
||||
|
||||
if (myMesh.IsNull())
|
||||
return;
|
||||
|
||||
update();
|
||||
update (theProgress);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : update()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::update()
|
||||
void BRepMesh_IncrementalMesh::update (const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
// Update edges data
|
||||
TopExp_Explorer aExplorer(myShape, TopAbs_EDGE);
|
||||
for (; aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
|
||||
if(!BRep_Tool::IsGeometric(aEdge))
|
||||
continue;
|
||||
Message_ProgressSentry anOuterSentry (theProgress, "Updating", 0, 100, 1);
|
||||
|
||||
update(aEdge);
|
||||
// Update edges data
|
||||
anOuterSentry.Next(9);
|
||||
{
|
||||
int aNbEdges = 0;
|
||||
for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
++aNbEdges;
|
||||
}
|
||||
|
||||
Message_ProgressSentry anEdgeSentry (theProgress, "Update edges data", 0, aNbEdges, 1);
|
||||
for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE);
|
||||
aExplorer.More() && anEdgeSentry.More(); aExplorer.Next(), anEdgeSentry.Next())
|
||||
{
|
||||
const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
|
||||
if(!BRep_Tool::IsGeometric(aEdge))
|
||||
continue;
|
||||
|
||||
update(aEdge);
|
||||
}
|
||||
}
|
||||
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
anOuterSentry.Next(5);
|
||||
|
||||
// Update faces data
|
||||
NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
|
||||
for (; aFaceIt.More(); aFaceIt.Next())
|
||||
for (Message_ProgressSentry aFacesSentry (theProgress, "Update faces data", 0, myFaces.Size(), 1);
|
||||
aFaceIt.More() && aFacesSentry.More(); aFaceIt.Next(), aFacesSentry.Next())
|
||||
{
|
||||
update(aFaceIt.Value());
|
||||
}
|
||||
|
||||
// Mesh faces
|
||||
OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel);
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
|
||||
commit();
|
||||
anOuterSentry.Next(80);
|
||||
|
||||
{
|
||||
// Mesh faces
|
||||
FaceListFunctor aFacesFunctor (this, theProgress, myParameters.InParallel);
|
||||
OSD_Parallel::For (0, myFaces.Size(), aFacesFunctor, !myParameters.InParallel);
|
||||
}
|
||||
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
|
||||
anOuterSentry.Next(5);
|
||||
{
|
||||
Message_ProgressSentry aSentry (theProgress, "Commit", 0, myFaces.Size(), 1);
|
||||
commit (aSentry);
|
||||
}
|
||||
anOuterSentry.Next();
|
||||
clear();
|
||||
}
|
||||
|
||||
@@ -493,10 +593,10 @@ void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace)
|
||||
//function : commit
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::commit()
|
||||
void BRepMesh_IncrementalMesh::commit (Message_ProgressSentry& theSentry)
|
||||
{
|
||||
NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
|
||||
for (; aFaceIt.More(); aFaceIt.Next())
|
||||
for (; aFaceIt.More() && theSentry.More(); aFaceIt.Next(), theSentry.Next())
|
||||
commitEdges(aFaceIt.Value());
|
||||
|
||||
discretizeFreeEdges();
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Message_ProgressIndicator;
|
||||
class Poly_Triangulation;
|
||||
class TopoDS_Shape;
|
||||
class TopoDS_Edge;
|
||||
@@ -68,7 +69,10 @@ public: //! @name mesher API
|
||||
|
||||
//! Performs meshing ot the shape.
|
||||
Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
|
||||
|
||||
|
||||
//! Performs meshing ot the shape.
|
||||
Standard_EXPORT void Perform(const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
public: //! @name accessing to parameters.
|
||||
|
||||
//! Returns meshing parameters
|
||||
@@ -126,7 +130,7 @@ protected:
|
||||
private:
|
||||
|
||||
//! Builds the incremental mesh for the shape.
|
||||
void update();
|
||||
void update(const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
//! Checks triangulation of the given face for consistency
|
||||
//! with the chosen tolerance. If some edge of face has no
|
||||
@@ -167,7 +171,7 @@ private:
|
||||
const Standard_Boolean isWithCheck);
|
||||
|
||||
//! Stores mesh to the shape.
|
||||
void commit();
|
||||
void commit(Message_ProgressSentry& theSentry);
|
||||
|
||||
//! Stores mesh of internal edges to the face.
|
||||
void commitEdges(const TopoDS_Face& theFace);
|
||||
@@ -175,6 +179,9 @@ private:
|
||||
//! Clears internal data structures.
|
||||
void clear();
|
||||
|
||||
private:
|
||||
class FaceListFunctor;
|
||||
|
||||
protected:
|
||||
|
||||
BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges;
|
||||
|
@@ -23,7 +23,8 @@ enum BRepMesh_Status
|
||||
BRepMesh_OpenWire = 0x1,
|
||||
BRepMesh_SelfIntersectingWire = 0x2,
|
||||
BRepMesh_Failure = 0x4,
|
||||
BRepMesh_ReMesh = 0x8
|
||||
BRepMesh_ReMesh = 0x8,
|
||||
BRepMesh_UserBreak = 0x16
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -2865,7 +2865,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
|
||||
const Standard_Boolean GlobalEnlargeVfirst,
|
||||
const Standard_Boolean GlobalEnlargeVlast)
|
||||
{
|
||||
const Standard_Real coeff = 2.; //4.;
|
||||
const Standard_Real coeff = 4.;
|
||||
const Standard_Real TolApex = 1.e-5;
|
||||
|
||||
Standard_Boolean SurfaceChange = Standard_False;
|
||||
@@ -3248,8 +3248,7 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
const Standard_Boolean UpdatePCurve,
|
||||
const Standard_Boolean enlargeU,
|
||||
const Standard_Boolean enlargeVfirst,
|
||||
const Standard_Boolean enlargeVlast,
|
||||
const Standard_Boolean UseInfini)
|
||||
const Standard_Boolean enlargeVlast)
|
||||
{
|
||||
//---------------------------
|
||||
// extension de la geometrie.
|
||||
@@ -3271,20 +3270,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
}
|
||||
|
||||
S->Bounds (US1,US2,VS1,VS2);
|
||||
if (UseInfini)
|
||||
{
|
||||
UU1 = VV1 = - TheInfini;
|
||||
UU2 = VV2 = TheInfini;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real FaceDU = UF2 - UF1;
|
||||
Standard_Real FaceDV = VF2 - VF1;
|
||||
UU1 = UF1 - FaceDU;
|
||||
UU2 = UF2 + FaceDU;
|
||||
VV1 = VF1 - FaceDV;
|
||||
VV2 = VF2 + FaceDV;
|
||||
}
|
||||
UU1 = VV1 = - TheInfini;
|
||||
UU2 = VV2 = TheInfini;
|
||||
|
||||
if (CanExtentSurface) {
|
||||
SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
|
||||
@@ -4161,4 +4148,4 @@ void PerformPlanes(const TopoDS_Face& theFace1,
|
||||
Standard_Boolean IsInf(const Standard_Real theVal)
|
||||
{
|
||||
return (theVal > TheInfini*0.9);
|
||||
}
|
||||
}
|
@@ -104,14 +104,7 @@ public:
|
||||
//! if <UpdatePCurve> is TRUE, update the pcurves of the
|
||||
//! edges of <F> on the new surface.if the surface has been changed,
|
||||
//! Returns True if The Surface of <NF> has changed.
|
||||
Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F,
|
||||
TopoDS_Face& NF,
|
||||
const Standard_Boolean ChangeGeom,
|
||||
const Standard_Boolean UpDatePCurve = Standard_False,
|
||||
const Standard_Boolean enlargeU = Standard_True,
|
||||
const Standard_Boolean enlargeVfirst = Standard_True,
|
||||
const Standard_Boolean enlargeVlast = Standard_True,
|
||||
const Standard_Boolean UseInfini = Standard_True);
|
||||
Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F, TopoDS_Face& NF, const Standard_Boolean ChangeGeom, const Standard_Boolean UpDatePCurve = Standard_False, const Standard_Boolean enlargeU = Standard_True, const Standard_Boolean enlargeVfirst = Standard_True, const Standard_Boolean enlargeVlast = Standard_True);
|
||||
|
||||
Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, TopTools_DataMapOfShapeShape& ToBuild, const TopAbs_State Side, const Standard_Real TolConf, TopoDS_Face& NF);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,111 +0,0 @@
|
||||
// Created on: 2012-08-06
|
||||
// Created by: jgv@ROLEX
|
||||
// Copyright (c) 2012-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 _BRepOffsetAPI_PatchFaces_HeaderFile
|
||||
#define _BRepOffsetAPI_PatchFaces_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
#include <TopTools_DataMapOfOrientedShapeShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <BRepBuilderAPI_MakeShape.hxx>
|
||||
class TopoDS_Shape;
|
||||
|
||||
|
||||
//! Describes functions to replace some faces in a shape
|
||||
//! by patches
|
||||
class BRepOffsetAPI_PatchFaces : public BRepBuilderAPI_MakeShape
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! General constructor.
|
||||
Standard_EXPORT BRepOffsetAPI_PatchFaces(const TopoDS_Shape& aShape);
|
||||
|
||||
//! Adds the patch face for the face in the shape.
|
||||
Standard_EXPORT void AddPatchFace (const TopoDS_Face& theFace, const TopoDS_Face& thePatchFace);
|
||||
|
||||
Standard_EXPORT virtual void Build() Standard_OVERRIDE;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Standard_EXPORT void UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEdge,
|
||||
TopoDS_Edge& thePrevNewEdge,
|
||||
const TopoDS_Edge& theCurEdge,
|
||||
TopoDS_Edge& theCurNewEdge,
|
||||
TopoDS_Vertex& theCurVertex,
|
||||
const TopoDS_Face& theFace,
|
||||
const TopoDS_Face& theNewFace,
|
||||
TopoDS_Face& theBoundedNewFace);
|
||||
|
||||
Standard_EXPORT void PutVertexToEdge(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Vertex& theProVertex,
|
||||
TopoDS_Edge& theEdge,
|
||||
const TopoDS_Edge& theProEdge,
|
||||
const Standard_Real theParamOnEdge);
|
||||
|
||||
Standard_EXPORT void ProjectVertexOnNewEdge_2d(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Face& theFace,
|
||||
const TopoDS_Edge& theNewEdge,
|
||||
const TopoDS_Face& theNewFace,
|
||||
Standard_Real& theParam,
|
||||
gp_Pnt& thePnt,
|
||||
gp_Pnt2d& thePnt2d,
|
||||
Standard_Real& theTolReached);
|
||||
|
||||
TopoDS_Shape myInitialShape;
|
||||
|
||||
TopTools_IndexedDataMapOfShapeShape myFacePatchFace;
|
||||
TopTools_IndexedDataMapOfShapeShape myFaceNewFace;
|
||||
TopTools_DataMapOfShapeShape myNewFaceBoundedFace;
|
||||
TopTools_DataMapOfShapeShape myEdgeNewEdge;
|
||||
//TopTools_DataMapOfOrientedShapeShape myOrientedEdgeNewEdge;
|
||||
TopTools_DataMapOfShapeShape myVertexNewVertex;
|
||||
TopTools_MapOfShape myTangentEdges;
|
||||
|
||||
TopTools_IndexedDataMapOfShapeListOfShape myEFmap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _BRepOffsetAPI_PatchFaces_HeaderFile
|
@@ -27,5 +27,3 @@ BRepOffsetAPI_SequenceOfSequenceOfShape.hxx
|
||||
BRepOffsetAPI_Sewing.hxx
|
||||
BRepOffsetAPI_ThruSections.cxx
|
||||
BRepOffsetAPI_ThruSections.hxx
|
||||
BRepOffsetAPI_PatchFaces.cxx
|
||||
BRepOffsetAPI_PatchFaces.hxx
|
||||
|
@@ -62,8 +62,6 @@
|
||||
#include <DBRep_DrawableShape.hxx>
|
||||
#include <BRepTest.hxx>
|
||||
|
||||
#include <BRepOffsetAPI_PatchFaces.hxx>
|
||||
|
||||
#include <BRepFilletAPI_MakeFillet.hxx>
|
||||
#include <ChFi3d_FilletShape.hxx>
|
||||
|
||||
@@ -2289,36 +2287,6 @@ static Standard_Integer ComputeSimpleOffset(Draw_Interpretor& theCommands,
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : patchfaces
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer patchfaces(Draw_Interpretor& /*di*/,
|
||||
Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n < 5) return 1;
|
||||
|
||||
TopoDS_Shape aShape = DBRep::Get(a[2]);
|
||||
if (aShape.IsNull()) return 1;
|
||||
|
||||
TopoDS_Shape aLocalFace = DBRep::Get(a[3], TopAbs_FACE);
|
||||
if (aLocalFace.IsNull()) return 1;
|
||||
TopoDS_Face aFace = TopoDS::Face(aLocalFace);
|
||||
|
||||
TopoDS_Shape aLocalNewFace = DBRep::Get(a[4], TopAbs_FACE);
|
||||
if (aLocalNewFace.IsNull()) return 1;
|
||||
TopoDS_Face aNewFace = TopoDS::Face(aLocalNewFace);
|
||||
|
||||
BRepOffsetAPI_PatchFaces Builder(aShape);
|
||||
Builder.AddPatchFace(aFace, aNewFace);
|
||||
Builder.Build();
|
||||
|
||||
TopoDS_Shape Result = Builder.Shape();
|
||||
DBRep::Set(a[1], Result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FeatureCommands
|
||||
//purpose :
|
||||
@@ -2467,7 +2435,4 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
|
||||
theCommands.Add("offsetshapesimple",
|
||||
"offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]",
|
||||
__FILE__, ComputeSimpleOffset);
|
||||
|
||||
theCommands.Add("patchfaces", "patchfaces res shape face newface",
|
||||
__FILE__,patchfaces,g);
|
||||
}
|
||||
|
@@ -800,29 +800,20 @@ proc testdiff {dir1 dir2 args} {
|
||||
|
||||
# Procedure to check data file before adding it to repository
|
||||
help testfile {
|
||||
Checks specified data files for putting them into the test data files repository.
|
||||
|
||||
Use: testfile filelist
|
||||
Check data file and prepare it for putting to test data files repository.
|
||||
Use: testfile [filelist]
|
||||
|
||||
Will report if:
|
||||
- data file (non-binary) is in DOS encoding (CR/LF)
|
||||
- same data file (with same or another name) already exists in the repository
|
||||
- another file with the same name already exists
|
||||
Note that names are considered to be case-insensitive (for compatibility
|
||||
with Windows).
|
||||
Note that names are assumed to be case-insensitive (for Windows).
|
||||
|
||||
Unless the file is already in the repository, tries to load it, reports
|
||||
the recognized file format, file size, number of faces and edges in the
|
||||
loaded shape (if any), information contained its triangulation, and makes
|
||||
snapshot (in the temporary directory).
|
||||
|
||||
loaded shape (if any), and makes snapshot (in the temporary directory).
|
||||
Finally it advises whether the file should be put to public section of the
|
||||
repository.
|
||||
|
||||
Use: testfile -check
|
||||
|
||||
If "-check" is given as an argument, then procedure will check files already
|
||||
located in the repository (for possible duplicates and for DOS encoding).
|
||||
}
|
||||
proc testfile {filelist} {
|
||||
global env
|
||||
@@ -832,11 +823,8 @@ proc testfile {filelist} {
|
||||
error "Environment variable CSF_TestDataPath must be defined!"
|
||||
}
|
||||
|
||||
set checkrepo f
|
||||
if { "$filelist" == "-check" } { set checkrepo t }
|
||||
|
||||
# build registry of existing data files (name -> path) and (size -> path)
|
||||
puts "Collecting info on test data files repository..."
|
||||
puts "Checking available test data files..."
|
||||
foreach dir [_split_path $env(CSF_TestDataPath)] {
|
||||
while {[llength $dir] != 0} {
|
||||
set curr [lindex $dir 0]
|
||||
@@ -845,143 +833,89 @@ proc testfile {filelist} {
|
||||
foreach file [glob -nocomplain -directory $curr -type f *] {
|
||||
set name [file tail $file]
|
||||
set name_lower [string tolower $name]
|
||||
set size [file size $file]
|
||||
|
||||
# check that the file is not in DOS encoding
|
||||
if { $checkrepo } {
|
||||
if { [_check_dos_encoding $file] } {
|
||||
puts "Warning: file $file is in DOS encoding; was this intended?"
|
||||
}
|
||||
_check_file_format $file
|
||||
if { [_check_dos_encoding $file] } {
|
||||
puts "Warning: file $file is in DOS encoding; was this intended?"
|
||||
}
|
||||
_check_file_format $file
|
||||
|
||||
# check if file with the same name is present twice or more
|
||||
if { [info exists names($name_lower)] } {
|
||||
puts "Error: more than one file with name $name is present in the repository:"
|
||||
if { [_diff_files $file $names($name_lower)] } {
|
||||
puts "(files are different by content)"
|
||||
} else {
|
||||
puts "(files are same by content)"
|
||||
}
|
||||
puts "--> $file"
|
||||
puts "--> $names($name_lower)"
|
||||
continue
|
||||
}
|
||||
# check if file with the same name is present twice or more
|
||||
if { [info exists names($name_lower)] } {
|
||||
puts "Error: more than one file with name $name is present in the repository:"
|
||||
if { [_diff_files $file $names($name_lower)] } {
|
||||
puts "(files are different by content)"
|
||||
} else {
|
||||
puts "(files are same by content)"
|
||||
}
|
||||
puts "--> $file"
|
||||
puts "--> $names($name_lower)"
|
||||
continue
|
||||
}
|
||||
|
||||
# check if file with the same content exists
|
||||
if { [info exists sizes($size)] } {
|
||||
foreach other $sizes($size) {
|
||||
if { ! [_diff_files $file $other] } {
|
||||
puts "Warning: two files with the same content found:"
|
||||
puts "--> $file"
|
||||
puts "--> $other"
|
||||
}
|
||||
# check if file with the same content exists
|
||||
set size [file size $file]
|
||||
if { [info exists sizes($size)] } {
|
||||
foreach other $sizes($size) {
|
||||
if { ! [_diff_files $file $other] } {
|
||||
puts "Warning: two files with the same content found:"
|
||||
puts "--> $file"
|
||||
puts "--> $other"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# add the file to the registry
|
||||
lappend names($name_lower) $file
|
||||
set names($name_lower) $file
|
||||
lappend sizes($size) $file
|
||||
}
|
||||
}
|
||||
}
|
||||
if { $checkrepo || [llength $filelist] <= 0 } { return }
|
||||
if { [llength $filelist] <= 0 } { return }
|
||||
|
||||
# check the new files
|
||||
set has_images f
|
||||
puts "Checking new file(s)..."
|
||||
foreach file $filelist {
|
||||
# check for DOS encoding
|
||||
if { [_check_dos_encoding $file] } {
|
||||
puts "$file: Warning: DOS encoding detected"
|
||||
}
|
||||
|
||||
set name [file tail $file]
|
||||
set name_lower [string tolower $name]
|
||||
set found f
|
||||
|
||||
# check for presence of the file with same name
|
||||
if { [info exists names($name_lower)] } {
|
||||
set found f
|
||||
foreach other $names($name_lower) {
|
||||
# avoid comparing the file with itself
|
||||
if { [file normalize $file] == [file normalize $other] } {
|
||||
continue
|
||||
}
|
||||
# compare content
|
||||
if { [_diff_files $file $other] } {
|
||||
puts "\n* $file: error\n name is already used by existing file\n --> $other"
|
||||
} else {
|
||||
puts "\n* $file: already present \n --> $other"
|
||||
}
|
||||
set found t
|
||||
break
|
||||
if { [_diff_files $file $names($name_lower)] } {
|
||||
puts "$file: Error: name is already used by existing file\n--> $names($name_lower)"
|
||||
} else {
|
||||
puts "$file: OK: already in the repository \n--> $names($name_lower)"
|
||||
continue
|
||||
}
|
||||
if { $found } { continue }
|
||||
}
|
||||
|
||||
# get size of the file; if it is in DOS encoding and less than 1 MB,
|
||||
# estimate also its size in UNIX encoding to be able to find same
|
||||
# file if already present but in UNIX encoding
|
||||
set sizeact [file size $file]
|
||||
set sizeunx ""
|
||||
set isdos [_check_dos_encoding $file]
|
||||
if { $isdos && $sizeact < 10000000 } {
|
||||
set fd [open $file r]
|
||||
fconfigure $fd -translation crlf
|
||||
set sizeunx [string length [read $fd]]
|
||||
close $fd
|
||||
}
|
||||
|
||||
# check if file with the same content exists
|
||||
foreach size "$sizeact $sizeunx" {
|
||||
if { [info exists sizes($size)] } {
|
||||
set size [file size $file]
|
||||
if { [info exists sizes($size)] } {
|
||||
set found f
|
||||
foreach other $sizes($size) {
|
||||
# avoid comparing the file with itself
|
||||
if { [file normalize $file] == [file normalize $other] } {
|
||||
continue
|
||||
}
|
||||
# compare content
|
||||
if { ! [_diff_files $file $other] } {
|
||||
puts "\n* $file: duplicate \n already present under name [file tail $other]\n --> $other"
|
||||
puts "$file: OK: the same file is already present under name [file tail $other]\n--> $other"
|
||||
set found t
|
||||
break
|
||||
}
|
||||
}
|
||||
if { $found } { break }
|
||||
}
|
||||
}
|
||||
if { $found } { continue }
|
||||
|
||||
# file is not present yet, so to be analyzed
|
||||
puts "\n* $file: new file"
|
||||
|
||||
# add the file to the registry as if it were added to the repository,
|
||||
# to report possible duplicates among the currently processed files
|
||||
lappend names($name_lower) $file
|
||||
if { "$sizeunx" != "" } {
|
||||
lappend sizes($sizeunx) $file
|
||||
} else {
|
||||
lappend sizes($sizeact) $file
|
||||
}
|
||||
|
||||
# first of all, complain if it is in DOS encoding
|
||||
if { $isdos } {
|
||||
puts " Warning: DOS encoding detected, consider converting to"
|
||||
puts " UNIX unless DOS line ends are needed for the test"
|
||||
if { $found } { continue }
|
||||
}
|
||||
|
||||
# try to read the file
|
||||
set format [_check_file_format $file]
|
||||
if { [catch {uplevel load_data_file $file $format a}] } {
|
||||
puts " Warning: Cannot read as $format file"
|
||||
puts "$file: Error: Cannot read as $format file"
|
||||
continue
|
||||
}
|
||||
|
||||
# warn if shape contains triangulation
|
||||
pload MODELING
|
||||
if { "$format" != "STL" &&
|
||||
[regexp {contains\s+([0-9]+)\s+triangles} [uplevel trinfo a] res nbtriangles] &&
|
||||
$nbtriangles != 0 } {
|
||||
puts " Warning: shape contains triangulation ($nbtriangles triangles),"
|
||||
puts " consider removing them unless they are needed for the test!"
|
||||
}
|
||||
|
||||
# get number of faces and edges
|
||||
set edges 0
|
||||
set faces 0
|
||||
@@ -994,10 +928,16 @@ proc testfile {filelist} {
|
||||
set dir public
|
||||
} else {
|
||||
set dir private
|
||||
# check if one of names of that file corresponds to typical name for
|
||||
# MDTV bugs or has extension .rle, this should be old model
|
||||
if { [regexp -nocase {.*(cts|ats|pro|buc|ger|fra|usa|uki)[0-9]+.*} $name] ||
|
||||
[regexp -nocase {[.]rle\y} $name] } {
|
||||
set dir old
|
||||
}
|
||||
}
|
||||
|
||||
# add stats
|
||||
puts " $format size=[expr $size / 1024] KiB, nbfaces=$faces, nbedges=$edges -> $dir"
|
||||
puts "$file: $format size=[expr $size / 1024] KiB, nbfaces=$faces, nbedges=$edges -> $dir"
|
||||
|
||||
set tmpdir [_get_temp_dir]
|
||||
file mkdir $tmpdir/$dir
|
||||
@@ -1005,7 +945,6 @@ proc testfile {filelist} {
|
||||
# make snapshot
|
||||
pload AISV
|
||||
uplevel vdisplay a
|
||||
uplevel vsetdispmode 1
|
||||
uplevel vfit
|
||||
uplevel vzfit
|
||||
uplevel vdump $tmpdir/$dir/[file rootname [file tail $file]].png
|
||||
@@ -1207,23 +1146,23 @@ proc _run_test {scriptsdir group gridname casefile echo} {
|
||||
# execute test scripts
|
||||
if { [file exists $scriptsdir/$group/begin] } {
|
||||
puts "Executing $scriptsdir/$group/begin..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/begin
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/begin
|
||||
}
|
||||
if { [file exists $scriptsdir/$group/$gridname/begin] } {
|
||||
puts "Executing $scriptsdir/$group/$gridname/begin..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/$gridname/begin
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/begin
|
||||
}
|
||||
|
||||
puts "Executing $casefile..."; flush stdout
|
||||
uplevel source $casefile
|
||||
uplevel source -encoding utf-8 $casefile
|
||||
|
||||
if { [file exists $scriptsdir/$group/$gridname/end] } {
|
||||
puts "Executing $scriptsdir/$group/$gridname/end..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/$gridname/end
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/end
|
||||
}
|
||||
if { [file exists $scriptsdir/$group/end] } {
|
||||
puts "Executing $scriptsdir/$group/end..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/end
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/end
|
||||
}
|
||||
} res] {
|
||||
puts "Tcl Exception: $res"
|
||||
@@ -1578,7 +1517,7 @@ proc _html_highlight {status line} {
|
||||
|
||||
# Internal procedure to generate HTML page presenting log of the tests
|
||||
# execution in tabular form, with links to reports on individual cases
|
||||
proc _log_html_summary {logdir log totals regressions improvements skipped total_time} {
|
||||
proc _log_html_summary {logdir log totals regressions improvements total_time} {
|
||||
global _test_case_regexp
|
||||
|
||||
# create missing directories as needed
|
||||
@@ -1625,7 +1564,7 @@ proc _log_html_summary {logdir log totals regressions improvements skipped total
|
||||
}
|
||||
|
||||
# print regressions and improvements
|
||||
foreach featured [list $regressions $improvements $skipped] {
|
||||
foreach featured [list $regressions $improvements] {
|
||||
if { [llength $featured] <= 1 } { continue }
|
||||
set status [string trim [lindex $featured 0] { :}]
|
||||
puts $fd "<h2>$status</h2>"
|
||||
@@ -1732,16 +1671,13 @@ proc _log_summarize {logdir log {total_time {}}} {
|
||||
set totals {}
|
||||
set improvements {Improvements:}
|
||||
set regressions {Failed:}
|
||||
set skipped {Skipped:}
|
||||
if { [info exists stat] } {
|
||||
foreach status [lsort [array names stat]] {
|
||||
lappend totals [list [llength $stat($status)] $status]
|
||||
|
||||
# separately count improvements (status starting with IMP), skipped (status starting with SKIP) and regressions (all except IMP, OK, BAD, and SKIP)
|
||||
# separately count improvements (status starting with IMP) and regressions (all except IMP, OK, BAD, and SKIP)
|
||||
if { [regexp -nocase {^IMP} $status] } {
|
||||
eval lappend improvements $stat($status)
|
||||
} elseif { [regexp -nocase {^SKIP} $status] } {
|
||||
eval lappend skipped $stat($status)
|
||||
} elseif { $status != "OK" && ! [regexp -nocase {^BAD} $status] && ! [regexp -nocase {^SKIP} $status] } {
|
||||
eval lappend regressions $stat($status)
|
||||
}
|
||||
@@ -1756,9 +1692,6 @@ proc _log_summarize {logdir log {total_time {}}} {
|
||||
if { [llength $regressions] > 1 } {
|
||||
_log_and_puts log [join $regressions "\n "]
|
||||
}
|
||||
if { [llength $skipped] > 1 } {
|
||||
_log_and_puts log [join $skipped "\n "]
|
||||
}
|
||||
if { [llength $improvements] == 1 && [llength $regressions] == 1 } {
|
||||
_log_and_puts log "No regressions"
|
||||
}
|
||||
@@ -1768,7 +1701,7 @@ proc _log_summarize {logdir log {total_time {}}} {
|
||||
|
||||
# save log to files
|
||||
if { $logdir != "" } {
|
||||
_log_html_summary $logdir $log $totals $regressions $improvements $skipped $total_time
|
||||
_log_html_summary $logdir $log $totals $regressions $improvements $total_time
|
||||
_log_save $logdir/tests.log [join $log "\n"] "Tests summary"
|
||||
}
|
||||
|
||||
@@ -2407,7 +2340,7 @@ proc load_data_file {file format shape} {
|
||||
DRAW { uplevel restore $file $shape }
|
||||
IGES { pload XSDRAW; uplevel igesbrep $file $shape * }
|
||||
STEP { pload XSDRAW; uplevel stepread $file __a *; uplevel renamevar __a_1 $shape }
|
||||
STL { pload XSDRAW; uplevel readstl $shape $file triangulation }
|
||||
STL { pload XSDRAW; uplevel readstl $shape $file }
|
||||
default { error "Cannot read $format file $file" }
|
||||
}
|
||||
}
|
||||
|
@@ -130,7 +130,7 @@ Standard_Boolean Expr_NamedUnknown::IsLinear () const
|
||||
Handle(Expr_GeneralExpression) Expr_NamedUnknown::Derivative (const Handle(Expr_NamedUnknown)& X) const
|
||||
{
|
||||
Handle(Expr_NamedUnknown) me = this;
|
||||
if (me != X) {
|
||||
if (!me->IsIdentical(X)) {
|
||||
if (IsAssigned()) {
|
||||
return myExpression->Derivative(X);
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Adaptor2d_Curve2d.hxx>
|
||||
#include <Extrema_Curve2dTool.hxx>
|
||||
#include <Extrema_ExtPC2d.hxx>
|
||||
#include <Extrema_POnCurv2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
@@ -43,6 +44,7 @@
|
||||
#define Pnt_hxx <gp_Pnt2d.hxx>
|
||||
#define Vec gp_Vec2d
|
||||
#define Vec_hxx <gp_Vec2d.hxx>
|
||||
#define Extrema_GExtPC Extrema_ExtPC2d
|
||||
#define Extrema_GenExtCC Extrema_ECC2d
|
||||
#define Extrema_GenExtCC_hxx <Extrema_ECC2d.hxx>
|
||||
#include <Extrema_GenExtCC.gxx>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Adaptor3d_Curve.hxx>
|
||||
#include <Extrema_CurveTool.hxx>
|
||||
#include <Extrema_ExtPC.hxx>
|
||||
#include <Extrema_POnCurv.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
@@ -43,6 +44,7 @@
|
||||
#define Pnt_hxx <gp_Pnt.hxx>
|
||||
#define Vec gp_Vec
|
||||
#define Vec_hxx <gp_Vec.hxx>
|
||||
#define Extrema_GExtPC Extrema_ExtPC
|
||||
#define Extrema_GenExtCC Extrema_ECC
|
||||
#define Extrema_GenExtCC_hxx <Extrema_ECC.hxx>
|
||||
#include <Extrema_GenExtCC.gxx>
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_ListOfInteger.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <NCollection_CellFilter.hxx>
|
||||
@@ -92,6 +93,29 @@ private:
|
||||
Standard_Boolean myIsFind;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : ProjPOnC
|
||||
//purpose : Projects the point on the curve and returns the minimal
|
||||
// projection distance
|
||||
//=======================================================================
|
||||
static Standard_Real ProjPOnC(const Pnt& theP,
|
||||
Extrema_GExtPC& theProjTool)
|
||||
{
|
||||
Standard_Real aDist = ::RealLast();
|
||||
theProjTool.Perform(theP);
|
||||
if (theProjTool.IsDone() && theProjTool.NbExt())
|
||||
{
|
||||
for (Standard_Integer i = 1; i <= theProjTool.NbExt(); ++i)
|
||||
{
|
||||
Standard_Real aD = theProjTool.SquareDistance(i);
|
||||
if (aD < aDist)
|
||||
aDist = aD;
|
||||
}
|
||||
aDist = sqrt(aDist);
|
||||
}
|
||||
return aDist;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Extrema_GenExtCC
|
||||
//purpose :
|
||||
@@ -262,9 +286,10 @@ void Extrema_GenExtCC::Perform()
|
||||
aFinder.SetFunctionalMinimalValue(0.0); // Best distance cannot be lower than 0.0.
|
||||
|
||||
// Size computed to have cell index inside of int32 value.
|
||||
const Standard_Real aCellSize = Max(anIntervals1.Last() - anIntervals1.First(),
|
||||
const Standard_Real aCellSize = Max(Max(anIntervals1.Last() - anIntervals1.First(),
|
||||
anIntervals2.Last() - anIntervals2.First())
|
||||
* Precision::PConfusion() / (2.0 * Sqrt(2.0));
|
||||
* Precision::PConfusion() / (2.0 * Sqrt(2.0)),
|
||||
Precision::PConfusion());
|
||||
Extrema_CCPointsInspector anInspector(aCellSize);
|
||||
NCollection_CellFilter<Extrema_CCPointsInspector> aFilter(aCellSize);
|
||||
NCollection_Vector<gp_XY> aPnts;
|
||||
@@ -329,63 +354,150 @@ void Extrema_GenExtCC::Perform()
|
||||
}
|
||||
}
|
||||
|
||||
if (aPnts.Size() == 0)
|
||||
const Standard_Integer aNbSol = aPnts.Length();
|
||||
if (aNbSol == 0)
|
||||
{
|
||||
// No solutions.
|
||||
myDone = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
myDone = Standard_True;
|
||||
|
||||
if (aNbSol == 1)
|
||||
{
|
||||
// Single solution
|
||||
const gp_XY& aSol = aPnts.First();
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
return;
|
||||
}
|
||||
|
||||
// More than one solution is found.
|
||||
// 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 solution.
|
||||
// If all midpoints functional value is acceptable then check the projection distances
|
||||
// of the bounding points of the curves onto the opposite curves.
|
||||
// If these distances are also acceptable set myParallel flag to true and return one solution.
|
||||
std::sort(aPnts.begin(), aPnts.end(), comp);
|
||||
Standard_Boolean isParallel = Standard_False;
|
||||
|
||||
// Solutions to pass into result.
|
||||
// If the parallel segment is found, save only extreme solutions on that segment.
|
||||
// The first and last solutions will always be the extreme ones, thus save them unconditionally.
|
||||
TColStd_ListOfInteger aSolutions;
|
||||
|
||||
// Manages the addition of the solution into result.
|
||||
// Set it to TRUE to add the first solution.
|
||||
Standard_Boolean bSaveSolution = Standard_True;
|
||||
|
||||
// Define direction of the second curve relatively the first one
|
||||
// (it will be needed for projection).
|
||||
Standard_Boolean bDirsCoinside = Standard_True;
|
||||
// Check also if the found solutions are not concentrated in one point
|
||||
// on any of the curves. And if they are, avoid marking the curves as parallel.
|
||||
Standard_Boolean bDifferentSolutions = Standard_False;
|
||||
|
||||
Standard_Boolean isParallel = Standard_True;
|
||||
Standard_Real aVal = 0.0;
|
||||
math_Vector aVec(1,2, 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.
|
||||
if (aPnts.Size() >= 2)
|
||||
// Iterate on all solutions and collect the extreme solutions on all parallel segments.
|
||||
for (Standard_Integer anIdx = 0; anIdx < aNbSol - 1; anIdx++)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
// It seems the parallel segment is found.
|
||||
// Save only extreme solutions on that segment.
|
||||
if (bSaveSolution)
|
||||
{
|
||||
isParallel = Standard_False;
|
||||
break;
|
||||
// Add current solution as the beginning of the parallel segment.
|
||||
aSolutions.Append(anIdx);
|
||||
// Do not keep the next solution in current parallel segment.
|
||||
bSaveSolution = Standard_False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mid point does not satisfy the tolerance criteria, curves are not parallel.
|
||||
isParallel = Standard_False;
|
||||
// Add current solution as the last one in previous parallel segment.
|
||||
aSolutions.Append(anIdx);
|
||||
// Save also the next solution as the first one in next parallel segment.
|
||||
bSaveSolution = Standard_True;
|
||||
}
|
||||
|
||||
if (!bDifferentSolutions)
|
||||
{
|
||||
if (aNext.X() > aCurrent.X())
|
||||
{
|
||||
if (aNext.Y() > aCurrent.Y())
|
||||
{
|
||||
bDifferentSolutions = Standard_True;
|
||||
bDirsCoinside = Standard_True;
|
||||
}
|
||||
else if (aNext.Y() < aCurrent.Y())
|
||||
{
|
||||
bDifferentSolutions = Standard_True;
|
||||
bDirsCoinside = Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save the last solution
|
||||
aSolutions.Append(aNbSol - 1);
|
||||
|
||||
if (!bDifferentSolutions)
|
||||
isParallel = Standard_False;
|
||||
|
||||
if (isParallel)
|
||||
{
|
||||
// For the check on parallel case it is also necessary to check additionally
|
||||
// if the ends of the curves do not diverge. For this, project the bounding
|
||||
// points of the curves on the opposite curves and check the distances.
|
||||
|
||||
Standard_Real aT1[2] = {myLowBorder(1), myUppBorder(1)};
|
||||
Standard_Real aT2[2] = {bDirsCoinside ? myLowBorder(2) : myUppBorder(2),
|
||||
bDirsCoinside ? myUppBorder(2) : myLowBorder(2)};
|
||||
|
||||
Extrema_GExtPC anExtPC1, anExtPC2;
|
||||
anExtPC1.Initialize(C1, myLowBorder(1), myUppBorder(1));
|
||||
anExtPC2.Initialize(C2, myLowBorder(2), myUppBorder(2));
|
||||
|
||||
for (Standard_Integer iT = 0; isParallel && (iT < 2); ++iT)
|
||||
{
|
||||
Standard_Real aDist1 = ProjPOnC(C1.Value(aT1[iT]), anExtPC2);
|
||||
Standard_Real aDist2 = ProjPOnC(C2.Value(aT2[iT]), anExtPC1);
|
||||
isParallel = (Abs(Min(aDist1, aDist2) - aF) < Precision::Confusion());
|
||||
}
|
||||
}
|
||||
|
||||
if (isParallel)
|
||||
{
|
||||
const gp_XY& aCurrent = aPnts.First();
|
||||
myPoints1.Append(aCurrent.X());
|
||||
myPoints2.Append(aCurrent.Y());
|
||||
// Keep only one solution
|
||||
const gp_XY& aSol = aPnts.First();
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
myParallel = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper(); anIdx++)
|
||||
// Keep all saved solutions
|
||||
TColStd_ListIteratorOfListOfInteger aItSol(aSolutions);
|
||||
for (; aItSol.More(); aItSol.Next())
|
||||
{
|
||||
const gp_XY& aCurrent = aPnts(anIdx);
|
||||
myPoints1.Append(aCurrent.X());
|
||||
myPoints2.Append(aCurrent.Y());
|
||||
const gp_XY& aSol = aPnts(aItSol.Value());
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
}
|
||||
}
|
||||
|
||||
myDone = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -12,8 +12,10 @@ Font_FTLibrary.hxx
|
||||
Font_NameOfFont.hxx
|
||||
Font_NListOfSystemFont.hxx
|
||||
Font_Rect.hxx
|
||||
Font_StrictLevel.hxx
|
||||
Font_SystemFont.cxx
|
||||
Font_SystemFont.hxx
|
||||
Font_NameOfFont.hxx
|
||||
Font_TextFormatter.hxx
|
||||
Font_TextFormatter.cxx
|
||||
Font_TextFormatter.cxx
|
||||
Font_UnicodeSubset.hxx
|
||||
|
@@ -15,10 +15,12 @@
|
||||
#include <Font_BRepFont.hxx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTopAdaptor_FClass2d.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepLib_MakeEdge.hxx>
|
||||
#include <Font_FTLibrary.hxx>
|
||||
#include <Font_FontMgr.hxx>
|
||||
#include <Font_TextFormatter.hxx>
|
||||
#include <GCE2d_MakeSegment.hxx>
|
||||
#include <GC_MakeSegment.hxx>
|
||||
@@ -34,9 +36,6 @@
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <TColGeom2d_HSequenceOfBoundedCurve.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
@@ -45,6 +44,9 @@
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
||||
#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@@ -57,6 +59,7 @@ namespace
|
||||
// pre-defined font rendering options
|
||||
static const unsigned int THE_FONT_SIZE = 72;
|
||||
static const unsigned int THE_RESOLUTION_DPI = 4800;
|
||||
static const Font_FTFontParams THE_FONT_PARAMS (THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
|
||||
// compute scaling factor for specified font size
|
||||
inline Standard_Real getScale (const Standard_Real theSize)
|
||||
@@ -66,9 +69,50 @@ namespace
|
||||
|
||||
//! Auxiliary method to convert FT_Vector to gp_XY
|
||||
static gp_XY readFTVec (const FT_Vector& theVec,
|
||||
const Standard_Real theScaleUnits)
|
||||
const Standard_Real theScaleUnits,
|
||||
const Standard_Real theWidthScaling = 1.0)
|
||||
{
|
||||
return gp_XY (theScaleUnits * Standard_Real(theVec.x) / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0);
|
||||
return gp_XY (theScaleUnits * Standard_Real(theVec.x) * theWidthScaling / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0);
|
||||
}
|
||||
|
||||
//! Auxiliary method for classification wire theW2 with respect to wire theW1
|
||||
static TopAbs_State classifyWW (const TopoDS_Wire& theW1,
|
||||
const TopoDS_Wire& theW2,
|
||||
const TopoDS_Face& theF)
|
||||
{
|
||||
TopAbs_State aRes = TopAbs_UNKNOWN;
|
||||
|
||||
TopoDS_Face aF = TopoDS::Face (theF.EmptyCopied());
|
||||
aF.Orientation (TopAbs_FORWARD);
|
||||
BRep_Builder aB;
|
||||
aB.Add (aF, theW1);
|
||||
BRepTopAdaptor_FClass2d aClass2d (aF, ::Precision::PConfusion());
|
||||
for (TopoDS_Iterator anEdgeIter (theW2); anEdgeIter.More(); anEdgeIter.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Value());
|
||||
Standard_Real aPFirst = 0.0, aPLast = 0.0;
|
||||
Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface (anEdge, theF, aPFirst, aPLast);
|
||||
if (aCurve2d.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gp_Pnt2d aPnt2d = aCurve2d->Value ((aPFirst + aPLast) / 2.0);
|
||||
TopAbs_State aState = aClass2d.Perform (aPnt2d, Standard_False);
|
||||
if (aState == TopAbs_OUT
|
||||
|| aState == TopAbs_IN)
|
||||
{
|
||||
if (aRes == TopAbs_UNKNOWN)
|
||||
{
|
||||
aRes = aState;
|
||||
}
|
||||
else if (aRes != aState)
|
||||
{
|
||||
return TopAbs_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return aRes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -97,15 +141,6 @@ void Font_BRepFont::init()
|
||||
myCurve2dAdaptor = new Geom2dAdaptor_HCurve();
|
||||
Handle(Adaptor3d_HSurface) aSurfAdaptor = new GeomAdaptor_HSurface (mySurface);
|
||||
myCurvOnSurf.Load (aSurfAdaptor);
|
||||
|
||||
myFixer.FixWireMode() = 1;
|
||||
myFixer.FixOrientationMode() = 1;
|
||||
myFixer.FixSplitFaceMode() = 1; // some glyphs might be composed from several faces
|
||||
Handle(ShapeFix_Wire) aWireFixer = myFixer.FixWireTool();
|
||||
aWireFixer->FixConnectedMode() = 1;
|
||||
aWireFixer->ClosedWireMode() = Standard_True;
|
||||
Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape();
|
||||
myFixer.SetContext (aContext);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -127,7 +162,7 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontPath,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
Font_FTFont::Init (theFontPath, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -136,7 +171,8 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontPath,
|
||||
// =======================================================================
|
||||
Font_BRepFont::Font_BRepFont (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize)
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
: myPrecision (Precision::Confusion()),
|
||||
myScaleUnits (1.0),
|
||||
myIsCompositeCurve (Standard_False),
|
||||
@@ -150,7 +186,7 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontName,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
Font_FTFont::Init (theFontName, theFontAspect, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -189,16 +225,17 @@ bool Font_BRepFont::Init (const NCollection_String& theFontPath,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
return Font_FTFont::Init (theFontPath, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
return Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// function : FindAndInit
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_BRepFont::Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize)
|
||||
bool Font_BRepFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
if (theSize <= myPrecision * 100.0)
|
||||
{
|
||||
@@ -206,7 +243,7 @@ bool Font_BRepFont::Init (const NCollection_String& theFontName,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
return Font_FTFont::Init (theFontName, theFontAspect, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
return Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -240,6 +277,131 @@ bool Font_BRepFont::to3d (const Handle(Geom2d_Curve)& theCurve2d,
|
||||
return !theCurve3d.IsNull();
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// function : buildFaces
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Font_BRepFont::buildFaces (const NCollection_Sequence<TopoDS_Wire>& theWires,
|
||||
TopoDS_Shape& theRes)
|
||||
{
|
||||
// classify wires
|
||||
NCollection_DataMap<TopoDS_Shape, NCollection_Sequence<TopoDS_Wire>, TopTools_ShapeMapHasher> aMapOutInts;
|
||||
TopTools_DataMapOfShapeInteger aMapNbOuts;
|
||||
TopoDS_Face aF;
|
||||
myBuilder.MakeFace (aF, mySurface, myPrecision);
|
||||
Standard_Integer aWireIter1Index = 1;
|
||||
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter1 (theWires); aWireIter1.More(); ++aWireIter1Index, aWireIter1.Next())
|
||||
{
|
||||
const TopoDS_Wire& aW1 = aWireIter1.Value();
|
||||
if (!aMapNbOuts.IsBound (aW1))
|
||||
{
|
||||
const Standard_Integer aNbOuts = 0;
|
||||
aMapNbOuts.Bind (aW1, aNbOuts);
|
||||
}
|
||||
|
||||
NCollection_Sequence<TopoDS_Wire>* anIntWs = aMapOutInts.Bound (aW1, NCollection_Sequence<TopoDS_Wire>());
|
||||
Standard_Integer aWireIter2Index = 1;
|
||||
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter2 (theWires); aWireIter2.More(); ++aWireIter2Index, aWireIter2.Next())
|
||||
{
|
||||
if (aWireIter1Index == aWireIter2Index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Wire& aW2 = aWireIter2.Value();
|
||||
const TopAbs_State aClass = classifyWW (aW1, aW2, aF);
|
||||
if (aClass == TopAbs_IN)
|
||||
{
|
||||
anIntWs->Append (aW2);
|
||||
if (Standard_Integer* aNbOutsPtr = aMapNbOuts.ChangeSeek (aW2))
|
||||
{
|
||||
++(*aNbOutsPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Integer aNbOuts = 1;
|
||||
aMapNbOuts.Bind (aW2, aNbOuts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check out wires and remove "not out" wires from maps
|
||||
for (TopTools_DataMapIteratorOfDataMapOfShapeInteger anOutIter (aMapNbOuts); anOutIter.More(); anOutIter.Next())
|
||||
{
|
||||
const Standard_Integer aTmp = anOutIter.Value() % 2;
|
||||
if (aTmp > 0)
|
||||
{
|
||||
// not out wire
|
||||
aMapOutInts.UnBind (anOutIter.Key());
|
||||
}
|
||||
}
|
||||
|
||||
// create faces for out wires
|
||||
TopTools_MapOfShape anUsedShapes;
|
||||
TopoDS_Compound aFaceComp;
|
||||
myBuilder.MakeCompound (aFaceComp);
|
||||
for (; !aMapOutInts.IsEmpty(); )
|
||||
{
|
||||
// find out wire with max number of outs
|
||||
TopoDS_Shape aW;
|
||||
Standard_Integer aMaxNbOuts = -1;
|
||||
for (NCollection_DataMap<TopoDS_Shape, NCollection_Sequence<TopoDS_Wire>, TopTools_ShapeMapHasher>::Iterator itMOI (aMapOutInts);
|
||||
itMOI.More(); itMOI.Next())
|
||||
{
|
||||
const TopoDS_Shape& aKey = itMOI.Key();
|
||||
const Standard_Integer aNbOuts = aMapNbOuts.Find (aKey);
|
||||
if (aNbOuts > aMaxNbOuts)
|
||||
{
|
||||
aMaxNbOuts = aNbOuts;
|
||||
aW = aKey;
|
||||
}
|
||||
}
|
||||
|
||||
// create face for selected wire
|
||||
TopoDS_Face aNewF;
|
||||
myBuilder.MakeFace (aNewF, mySurface, myPrecision);
|
||||
myBuilder.Add (aNewF, aW);
|
||||
anUsedShapes.Add (aW);
|
||||
const NCollection_Sequence<TopoDS_Wire>& anIns = aMapOutInts.Find (aW);
|
||||
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter (anIns); aWireIter.More(); aWireIter.Next())
|
||||
{
|
||||
TopoDS_Wire aWin = aWireIter.Value();
|
||||
if (anUsedShapes.Contains (aWin))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aWin.Reverse();
|
||||
myBuilder.Add (aNewF, aWin);
|
||||
anUsedShapes.Add (aWin);
|
||||
}
|
||||
|
||||
myBuilder.Add (aFaceComp, aNewF);
|
||||
aMapOutInts.UnBind (aW);
|
||||
}
|
||||
|
||||
TopoDS_Iterator anExplor (aFaceComp);
|
||||
if (!anExplor.More()) //if (aFaceComp.NbChildren() == 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
TopoDS_Shape aSingleShape = anExplor.Value(); anExplor.Next();
|
||||
if (!anExplor.More()) //if (aFaceComp.NbChildren() == 1)
|
||||
{
|
||||
//theRes = TopoDS_Iterator (aFaceComp).Value();
|
||||
theRes = aSingleShape;
|
||||
}
|
||||
else
|
||||
{
|
||||
theRes = aFaceComp;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// function : renderGlyph
|
||||
// purpose :
|
||||
@@ -249,7 +411,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
{
|
||||
theShape.Nullify();
|
||||
if (!loadGlyph (theChar)
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -258,14 +420,13 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
return !theShape.IsNull();
|
||||
}
|
||||
|
||||
FT_Outline& anOutline = myFTFace->glyph->outline;
|
||||
|
||||
const FT_Outline& anOutline = myActiveFTFace->glyph->outline;
|
||||
if (!anOutline.n_contours)
|
||||
return Standard_False;
|
||||
|
||||
TopLoc_Location aLoc;
|
||||
TopoDS_Face aFaceDraft;
|
||||
myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision);
|
||||
NCollection_Sequence<TopoDS_Wire> aWires;
|
||||
TopoDS_Compound aFaceCompDraft;
|
||||
|
||||
// Get orientation is useless since it doesn't retrieve any in-font information and just computes orientation.
|
||||
// Because it fails in some cases - leave this to ShapeFix.
|
||||
@@ -277,7 +438,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
const short anEndIndex = anOutline.contours[aContour];
|
||||
const short aPntsNb = (anEndIndex - aStartIndex) + 1;
|
||||
aStartIndex = anEndIndex + 1;
|
||||
if (aPntsNb < 3)
|
||||
if (aPntsNb < 3 && !myFontParams.IsSingleStrokeFont)
|
||||
{
|
||||
// closed contour can not be constructed from < 3 points
|
||||
continue;
|
||||
@@ -286,10 +447,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
BRepBuilderAPI_MakeWire aWireMaker;
|
||||
|
||||
gp_XY aPntPrev;
|
||||
gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits);
|
||||
gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits);
|
||||
gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling);
|
||||
gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling);
|
||||
|
||||
Standard_Integer aLinePnts = (FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On) ? 1 : 0;
|
||||
bool isLineSeg = !myFontParams.IsSingleStrokeFont
|
||||
&& FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On;
|
||||
gp_XY aPntLine1 = aPntCurr;
|
||||
|
||||
// see http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html
|
||||
@@ -298,15 +460,15 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
{
|
||||
aPntPrev = aPntCurr;
|
||||
aPntCurr = aPntNext;
|
||||
aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits);
|
||||
aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling);
|
||||
|
||||
// process tags
|
||||
if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On)
|
||||
{
|
||||
if (aLinePnts < 1)
|
||||
if (!isLineSeg)
|
||||
{
|
||||
aPntLine1 = aPntCurr;
|
||||
aLinePnts = 1;
|
||||
isLineSeg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -315,7 +477,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
if (aLen <= myPrecision)
|
||||
{
|
||||
aPntLine1 = aPntCurr;
|
||||
aLinePnts = 1;
|
||||
isLineSeg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -339,7 +501,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
}
|
||||
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Conic)
|
||||
{
|
||||
aLinePnts = 0;
|
||||
isLineSeg = false;
|
||||
gp_XY aPntPrev2 = aPntPrev;
|
||||
gp_XY aPntNext2 = aPntNext;
|
||||
|
||||
@@ -378,11 +540,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Cubic
|
||||
&& FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Cubic)
|
||||
{
|
||||
aLinePnts = 0;
|
||||
isLineSeg = false;
|
||||
my4Poles.SetValue (1, aPntPrev);
|
||||
my4Poles.SetValue (2, aPntCurr);
|
||||
my4Poles.SetValue (3, aPntNext);
|
||||
my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits)));
|
||||
my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling)));
|
||||
Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles);
|
||||
if (myIsCompositeCurve)
|
||||
{
|
||||
@@ -411,7 +573,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
|
||||
const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint();
|
||||
const gp_Pnt2d aLastPnt = aDraft2d->EndPoint();
|
||||
if (!aFirstPnt.IsEqual (aLastPnt, myPrecision))
|
||||
if (!myFontParams.IsSingleStrokeFont
|
||||
&& !aFirstPnt.IsEqual (aLastPnt, myPrecision))
|
||||
{
|
||||
Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt);
|
||||
myConcatMaker.Add (aLine, myPrecision);
|
||||
@@ -438,7 +601,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV);
|
||||
gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV);
|
||||
gp_Pnt aLastPoint = BRep_Tool::Pnt (aLastV);
|
||||
if (!aFirstPoint.IsEqual (aLastPoint, myPrecision))
|
||||
if (!myFontParams.IsSingleStrokeFont
|
||||
&& !aFirstPoint.IsEqual (aLastPoint, myPrecision))
|
||||
{
|
||||
aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV));
|
||||
}
|
||||
@@ -450,31 +614,38 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
}
|
||||
|
||||
TopoDS_Wire aWireDraft = aWireMaker.Wire();
|
||||
//if (anOrient == FT_ORIENTATION_FILL_LEFT)
|
||||
//{
|
||||
// According to the TrueType specification, clockwise contours must be filled
|
||||
aWireDraft.Reverse();
|
||||
//}
|
||||
myBuilder.Add (aFaceDraft, aWireDraft);
|
||||
if (!myFontParams.IsSingleStrokeFont)
|
||||
{
|
||||
// collect all wires and set CCW orientation
|
||||
TopoDS_Face aFace;
|
||||
myBuilder.MakeFace (aFace, mySurface, myPrecision);
|
||||
myBuilder.Add (aFace, aWireDraft);
|
||||
BRepTopAdaptor_FClass2d aClass2d (aFace, ::Precision::PConfusion());
|
||||
TopAbs_State aState = aClass2d.PerformInfinitePoint();
|
||||
if (aState != TopAbs_OUT)
|
||||
{
|
||||
// need to reverse
|
||||
aWireDraft.Reverse();
|
||||
}
|
||||
aWires.Append (aWireDraft);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aFaceCompDraft.IsNull())
|
||||
{
|
||||
myBuilder.MakeCompound (aFaceCompDraft);
|
||||
}
|
||||
myBuilder.Add (aFaceCompDraft, aWireDraft);
|
||||
}
|
||||
}
|
||||
|
||||
myFixer.Init (aFaceDraft);
|
||||
myFixer.Perform();
|
||||
theShape = myFixer.Result();
|
||||
if (!theShape.IsNull()
|
||||
&& theShape.ShapeType() != TopAbs_FACE)
|
||||
if (!aWires.IsEmpty())
|
||||
{
|
||||
// shape fix can not fix orientation within the single call
|
||||
TopoDS_Compound aComp;
|
||||
myBuilder.MakeCompound (aComp);
|
||||
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
|
||||
{
|
||||
TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current());
|
||||
myFixer.Init (aFace);
|
||||
myFixer.Perform();
|
||||
myBuilder.Add (aComp, myFixer.Result());
|
||||
}
|
||||
theShape = aComp;
|
||||
buildFaces (aWires, theShape);
|
||||
}
|
||||
else if (!aFaceCompDraft.IsNull())
|
||||
{
|
||||
theShape = aFaceCompDraft;
|
||||
}
|
||||
|
||||
myCache.Bind (theChar, theShape);
|
||||
|
@@ -27,10 +27,12 @@
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_String.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_BRepFont, Font_FTFont)
|
||||
|
||||
//! This tool provides basic services for rendering of vectorized text glyphs as BRep shapes.
|
||||
//! Single instance initialize single font for sequential glyphs rendering with implicit caching of already rendered glyphs.
|
||||
@@ -41,6 +43,7 @@
|
||||
//! Although caching should eliminate this issue after rendering of sufficient number of glyphs.
|
||||
class Font_BRepFont : protected Font_FTFont
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_BRepFont, Font_FTFont)
|
||||
public:
|
||||
|
||||
//! Empty constructor
|
||||
@@ -53,12 +56,14 @@ public:
|
||||
const Standard_Real theSize);
|
||||
|
||||
//! Constructor with initialization.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theSize the face size in model units
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theSize the face size in model units
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
Standard_EXPORT Font_BRepFont (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize);
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Release currently loaded font.
|
||||
Standard_EXPORT virtual void Release() Standard_OVERRIDE;
|
||||
@@ -70,7 +75,7 @@ public:
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontPath,
|
||||
const Standard_Real theSize);
|
||||
|
||||
//! Initialize the font.
|
||||
//! Find (using Font_FontMgr) and initialize the font from the given name.
|
||||
//! Please take into account that size is specified NOT in typography points (pt.).
|
||||
//! If you need to specify size in points, value should be converted.
|
||||
//! Formula for pt. -> m conversion:
|
||||
@@ -78,10 +83,12 @@ public:
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theSize the face size in model units
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize);
|
||||
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Render single glyph as TopoDS_Shape.
|
||||
//! @param theChar glyph identifier
|
||||
@@ -96,6 +103,13 @@ public:
|
||||
//! Notice that altering this flag clears currently accumulated cache!
|
||||
Standard_EXPORT void SetCompositeCurveMode (const Standard_Boolean theToConcatenate);
|
||||
|
||||
//! Setup glyph scaling along X-axis.
|
||||
//! By default glyphs are not scaled (scaling factor = 1.0)
|
||||
void SetWidthScaling (const float theScaleFactor)
|
||||
{
|
||||
myWidthScaling = theScaleFactor;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
|
||||
@@ -164,6 +178,17 @@ public:
|
||||
return myMutex;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Find (using Font_FontMgr) and initialize the font from the given name.
|
||||
//! Alias for FindAndInit() for backward compatibility.
|
||||
bool Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize)
|
||||
{
|
||||
return FindAndInit (theFontName.ToCString(), theFontAspect, theSize, Font_StrictLevel_Any);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Render single glyph as TopoDS_Shape. This method does not lock the mutex.
|
||||
@@ -183,6 +208,14 @@ private:
|
||||
const GeomAbs_Shape theContinuity,
|
||||
Handle(Geom_Curve)& theCurve3d);
|
||||
|
||||
//! Auxiliary method for creation faces from sequence of wires.
|
||||
//! Splits to few faces (if it is needed) and updates orientation of wires.
|
||||
Standard_Boolean buildFaces (const NCollection_Sequence<TopoDS_Wire>& theWires,
|
||||
TopoDS_Shape& theRes);
|
||||
|
||||
//! Hide visibility.
|
||||
using Font_FTFont::FindAndCreate;
|
||||
|
||||
protected: //! @name Protected fields
|
||||
|
||||
NCollection_DataMap<Standard_Utf32Char, TopoDS_Shape>
|
||||
@@ -201,15 +234,7 @@ protected: //! @name Shared temporary variables for glyph construction
|
||||
TColgp_Array1OfPnt2d my3Poles;
|
||||
TColgp_Array1OfPnt2d my4Poles;
|
||||
BRep_Builder myBuilder;
|
||||
ShapeFix_Face myFixer;
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_BRepFont,Font_FTFont)
|
||||
|
||||
};
|
||||
|
||||
// Definition of HANDLE object using Standard_DefineHandle.hxx
|
||||
DEFINE_STANDARD_HANDLE(Font_BRepFont, Font_FTFont)
|
||||
|
||||
#endif // _Font_BRepFont_H__
|
||||
|
@@ -18,6 +18,10 @@
|
||||
#include <Font_FTLibrary.hxx>
|
||||
#include <Font_FontMgr.hxx>
|
||||
#include <Font_TextFormatter.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@@ -29,12 +33,14 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
||||
: myFTLib (theFTLib),
|
||||
myFTFace (NULL),
|
||||
myPointSize (0U),
|
||||
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
||||
myKernAdvance(new FT_Vector()),
|
||||
myUChar (0U)
|
||||
: myFTLib (theFTLib),
|
||||
myFTFace (NULL),
|
||||
myActiveFTFace(NULL),
|
||||
myFontAspect (Font_FontAspect_Regular),
|
||||
myWidthScaling(1.0),
|
||||
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
||||
myUChar (0U),
|
||||
myToUseUnicodeSubsetFallback (Font_FontMgr::ToUseUnicodeSubsetFallback())
|
||||
{
|
||||
if (myFTLib.IsNull())
|
||||
{
|
||||
@@ -49,7 +55,6 @@ Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
||||
Font_FTFont::~Font_FTFont()
|
||||
{
|
||||
Release();
|
||||
delete myKernAdvance;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -66,61 +71,173 @@ void Font_FTFont::Release()
|
||||
FT_Done_Face (myFTFace);
|
||||
myFTFace = NULL;
|
||||
}
|
||||
myActiveFTFace = NULL;
|
||||
myBuffer.Nullify();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::Init (const NCollection_String& theFontPath,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution)
|
||||
bool Font_FTFont::Init (const Handle(NCollection_Buffer)& theData,
|
||||
const TCollection_AsciiString& theFileName,
|
||||
const Font_FTFontParams& theParams)
|
||||
{
|
||||
Release();
|
||||
myFontPath = theFontPath;
|
||||
myPointSize = thePointSize;
|
||||
myBuffer = theData;
|
||||
myFontPath = theFileName;
|
||||
myFontParams = theParams;
|
||||
if (!myFTLib->IsValid())
|
||||
{
|
||||
//std::cerr << "FreeType library is unavailable!\n";
|
||||
Message::DefaultMessenger()->Send ("FreeType library is unavailable", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
|
||||
if (!theData.IsNull())
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' fail to load!\n";
|
||||
if (FT_New_Memory_Face (myFTLib->Instance(), theData->Data(), (FT_Long )theData->Size(), 0, &myFTFace) != 0)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' failed to load from memory", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
|
||||
{
|
||||
//Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' failed to load from file", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' doesn't contains Unicode charmap", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
|
||||
else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (theParams.PointSize), theParams.Resolution, theParams.Resolution) != 0)
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' doesn't contains Unicode charmap of requested size", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
|
||||
|
||||
if (theParams.ToSynthesizeItalic)
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
|
||||
Release();
|
||||
return false;
|
||||
const double THE_SHEAR_ANGLE = 10.0 * M_PI / 180.0;
|
||||
|
||||
FT_Matrix aMat;
|
||||
aMat.xx = FT_Fixed (Cos (-THE_SHEAR_ANGLE) * (1 << 16));
|
||||
aMat.xy = 0;
|
||||
aMat.yx = 0;
|
||||
aMat.yy = aMat.xx;
|
||||
|
||||
FT_Fixed aFactor = FT_Fixed (Tan (THE_SHEAR_ANGLE) * (1 << 16));
|
||||
aMat.xy += FT_MulFix (aFactor, aMat.xx);
|
||||
|
||||
FT_Set_Transform (myFTFace, &aMat, 0);
|
||||
}
|
||||
myActiveFTFace = myFTFace;
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// function : FindAndCreate
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution)
|
||||
Handle(Font_FTFont) Font_FTFont::FindAndCreate (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
|
||||
Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
|
||||
return !aRequestedFont.IsNull()
|
||||
&& Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName, theStrictLevel, aFontAspect))
|
||||
{
|
||||
Font_FTFontParams aParams = theParams;
|
||||
if (aRequestedFont->IsSingleStrokeFont())
|
||||
{
|
||||
aParams.IsSingleStrokeFont = true;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (aFontAspect, aParams.ToSynthesizeItalic);
|
||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||
if (aFont->Init (aPath, aParams))
|
||||
{
|
||||
aFont->myFontAspect = aFontAspect;
|
||||
return aFont;
|
||||
}
|
||||
}
|
||||
return Handle(Font_FTFont)();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FindAndInit
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
Font_FTFontParams aParams = theParams;
|
||||
myFontAspect = theFontAspect;
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName.ToCString(), theStrictLevel, myFontAspect))
|
||||
{
|
||||
if (aRequestedFont->IsSingleStrokeFont())
|
||||
{
|
||||
aParams.IsSingleStrokeFont = true;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||
return Init (aPath, aParams);
|
||||
}
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : findAndInitFallback
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::findAndInitFallback (Font_UnicodeSubset theSubset)
|
||||
{
|
||||
if (!myFallbackFaces[theSubset].IsNull())
|
||||
{
|
||||
return myFallbackFaces[theSubset]->IsValid();
|
||||
}
|
||||
|
||||
myFallbackFaces[theSubset] = new Font_FTFont (myFTLib);
|
||||
myFallbackFaces[theSubset]->myToUseUnicodeSubsetFallback = false; // no recursion
|
||||
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFallbackFont (theSubset, myFontAspect))
|
||||
{
|
||||
Font_FTFontParams aParams = myFontParams;
|
||||
aParams.IsSingleStrokeFont = aRequestedFont->IsSingleStrokeFont();
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||
if (myFallbackFaces[theSubset]->Init (aPath, aParams))
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Font_FTFont, using fallback font '") + aRequestedFont->FontName() + "'"
|
||||
+ " for symbols unsupported by '" + myFTFace->family_name + "'", Message_Trace);
|
||||
}
|
||||
}
|
||||
return myFallbackFaces[theSubset]->IsValid();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : HasSymbol
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::HasSymbol (Standard_Utf32Char theUChar) const
|
||||
{
|
||||
return FT_Get_Char_Index (myFTFace, theUChar) != 0;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -131,14 +248,31 @@ bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
|
||||
{
|
||||
if (myUChar == theUChar)
|
||||
{
|
||||
return true;
|
||||
return myUChar != 0;
|
||||
}
|
||||
|
||||
myGlyphImg.Clear();
|
||||
myUChar = 0;
|
||||
if (theUChar == 0
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||
|| myFTFace->glyph == NULL)
|
||||
myActiveFTFace = myFTFace;
|
||||
if (theUChar == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myToUseUnicodeSubsetFallback
|
||||
&& !HasSymbol (theUChar))
|
||||
{
|
||||
// try using fallback
|
||||
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||
if (findAndInitFallback (aSubset)
|
||||
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||
{
|
||||
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||
}
|
||||
}
|
||||
|
||||
if (FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||
|| myActiveFTFace->glyph == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -155,26 +289,68 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
{
|
||||
myGlyphImg.Clear();
|
||||
myUChar = 0;
|
||||
myActiveFTFace = myFTFace;
|
||||
|
||||
if (theUChar != 0
|
||||
&& myToUseUnicodeSubsetFallback
|
||||
&& !HasSymbol (theUChar))
|
||||
{
|
||||
// try using fallback
|
||||
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||
if (findAndInitFallback (aSubset)
|
||||
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||
{
|
||||
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||
}
|
||||
}
|
||||
|
||||
if (theUChar == 0
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myFTFace->glyph == NULL
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
|| FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myActiveFTFace->glyph == NULL
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
|
||||
if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
|
||||
|| aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
FT_Bitmap aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
if (aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||
|
||||
if (aBitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||
{
|
||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
}
|
||||
else if (aBitmap.pixel_mode == FT_PIXEL_MODE_MONO)
|
||||
{
|
||||
if (!myGlyphImg.InitTrash (Image_Format_Gray, aBitmap.width, aBitmap.rows))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
const int aNumOfBytesInRow = aBitmap.width / 8 + (aBitmap.width % 8 ? 1 : 0);
|
||||
for (int aRow = 0; aRow < (int )aBitmap.rows; ++aRow)
|
||||
{
|
||||
for (int aCol = 0; aCol < (int )aBitmap.width; ++aCol)
|
||||
{
|
||||
const int aBitOn = aBitmap.buffer[aNumOfBytesInRow * aRow + aCol / 8] & (0x80 >> (aCol % 8));
|
||||
//*myGlyphImg.ChangeRawValue (aRow, aCol) = aBitOn ? 255 : 0;
|
||||
myGlyphImg.ChangeRow (aRow)[aCol] = aBitOn ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
|
||||
myUChar = theUChar;
|
||||
return true;
|
||||
}
|
||||
@@ -183,24 +359,58 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
// function : GlyphMaxSizeX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX (bool theToIncludeFallback) const
|
||||
{
|
||||
float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||
return (unsigned int)(aWidth + 0.5f);
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||
return (unsigned int)(aWidth + 0.5f);
|
||||
}
|
||||
|
||||
unsigned int aWidth = GlyphMaxSizeX (false);
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aWidth = std::max (aWidth, myFallbackFaces[aFontIter]->GlyphMaxSizeX (false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return aWidth;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GlyphMaxSizeY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY (bool theToIncludeFallback) const
|
||||
{
|
||||
float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||
return (unsigned int)(aHeight + 0.5f);
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||
return (unsigned int)(aHeight + 0.5f);
|
||||
}
|
||||
|
||||
unsigned int aHeight = GlyphMaxSizeY (false);
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aHeight = std::max (aHeight, myFallbackFaces[aFontIter]->GlyphMaxSizeY (false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return aHeight;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -234,8 +444,8 @@ float Font_FTFont::LineSpacing() const
|
||||
// function : AdvanceX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceX (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext)
|
||||
{
|
||||
loadGlyph (theUChar);
|
||||
return AdvanceX (theUCharNext);
|
||||
@@ -245,71 +455,103 @@ float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
|
||||
// function : AdvanceY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceY (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext)
|
||||
{
|
||||
loadGlyph (theUChar);
|
||||
return AdvanceY (theUCharNext);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : getKerning
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::getKerning (FT_Vector& theKern,
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
theKern.x = 0;
|
||||
theKern.y = 0;
|
||||
if (theUCharNext != 0 && FT_HAS_KERNING(myActiveFTFace) != 0)
|
||||
{
|
||||
const FT_UInt aCharCurr = FT_Get_Char_Index (myActiveFTFace, theUCharCurr);
|
||||
const FT_UInt aCharNext = FT_Get_Char_Index (myActiveFTFace, theUCharNext);
|
||||
if (aCharCurr == 0 || aCharNext == 0
|
||||
|| FT_Get_Kerning (myActiveFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0)
|
||||
{
|
||||
theKern.x = 0;
|
||||
theKern.y = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AdvanceX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
if (myUChar == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
|
||||
|| FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
|
||||
{
|
||||
return fromFTPoints<float> (myFTFace->glyph->advance.x);
|
||||
}
|
||||
return fromFTPoints<float> (myKernAdvance->x + myFTFace->glyph->advance.x);
|
||||
FT_Vector aKern;
|
||||
getKerning (aKern, myUChar, theUCharNext);
|
||||
return myWidthScaling * fromFTPoints<float> (myActiveFTFace->glyph->advance.x + aKern.x);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AdvanceY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceY (Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
if (myUChar == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
|
||||
|| FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
|
||||
{
|
||||
return fromFTPoints<float> (myFTFace->glyph->advance.y);
|
||||
}
|
||||
return fromFTPoints<float> (myKernAdvance->y + myFTFace->glyph->advance.y);
|
||||
FT_Vector aKern;
|
||||
getKerning (aKern, myUChar, theUCharNext);
|
||||
return fromFTPoints<float> (myActiveFTFace->glyph->advance.y + aKern.y);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GlyphsNumber
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Font_FTFont::GlyphsNumber() const
|
||||
Standard_Integer Font_FTFont::GlyphsNumber (bool theToIncludeFallback) const
|
||||
{
|
||||
return myFTFace->num_glyphs;
|
||||
Standard_Integer aNbGlyphs = myFTFace->num_glyphs;
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aNbGlyphs += myFallbackFaces[aFontIter]->GlyphsNumber (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aNbGlyphs;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : theRect
|
||||
// function : GlyphRect
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_FTFont::GlyphRect (Font_Rect& theRect) const
|
||||
{
|
||||
const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
const FT_Bitmap& aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myActiveFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myActiveFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myActiveFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myActiveFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -18,21 +18,120 @@
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Font_Rect.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
||||
#include <Graphic3d_VerticalTextAlignment.hxx>
|
||||
#include <Image_PixMap.hxx>
|
||||
#include <NCollection_String.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
// forward declarations to avoid including of FreeType headers
|
||||
typedef struct FT_FaceRec_* FT_Face;
|
||||
typedef struct FT_Vector_ FT_Vector;
|
||||
class Font_FTLibrary;
|
||||
|
||||
//! Font initialization parameters.
|
||||
struct Font_FTFontParams
|
||||
{
|
||||
unsigned int PointSize; //!< face size in points (1/72 inch)
|
||||
unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size()
|
||||
bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default
|
||||
bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default
|
||||
|
||||
//! Empty constructor.
|
||||
Font_FTFontParams() : PointSize (0), Resolution (72u), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {}
|
||||
|
||||
//! Constructor.
|
||||
Font_FTFontParams (unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
: PointSize (thePointSize), Resolution (theResolution), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {}
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient)
|
||||
|
||||
//! Wrapper over FreeType font.
|
||||
//! Notice that this class uses internal buffers for loaded glyphs
|
||||
//! and it is absolutely UNSAFE to load/read glyph from concurrent threads!
|
||||
class Font_FTFont : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FTFont, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Find the font Initialize the font.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theParams initialization parameters
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
//! @return true on success
|
||||
Standard_EXPORT static Handle(Font_FTFont) FindAndCreate (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Return TRUE if specified character is within subset of modern CJK characters.
|
||||
static bool IsCharFromCJK (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x03400 && theUChar <= 0x04DFF)
|
||||
|| (theUChar >= 0x04E00 && theUChar <= 0x09FFF)
|
||||
|| (theUChar >= 0x0F900 && theUChar <= 0x0FAFF)
|
||||
|| (theUChar >= 0x20000 && theUChar <= 0x2A6DF)
|
||||
|| (theUChar >= 0x2F800 && theUChar <= 0x2FA1F)
|
||||
// Hiragana and Katakana (Japanese) are NOT part of CJK, but CJK fonts usually include these symbols
|
||||
|| IsCharFromHiragana (theUChar)
|
||||
|| IsCharFromKatakana (theUChar);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Hiragana (Japanese).
|
||||
static bool IsCharFromHiragana (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x03040 && theUChar <= 0x0309F);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Katakana (Japanese).
|
||||
static bool IsCharFromKatakana (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x030A0 && theUChar <= 0x030FF);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of modern Korean characters (Hangul).
|
||||
static bool IsCharFromKorean (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x01100 && theUChar <= 0x011FF)
|
||||
|| (theUChar >= 0x03130 && theUChar <= 0x0318F)
|
||||
|| (theUChar >= 0x0AC00 && theUChar <= 0x0D7A3);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Arabic characters.
|
||||
static bool IsCharFromArabic (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x00600 && theUChar <= 0x006FF);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character should be displayed in Right-to-Left order.
|
||||
static bool IsCharRightToLeft (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return IsCharFromArabic(theUChar);
|
||||
}
|
||||
|
||||
//! Determine Unicode subset for specified character
|
||||
static Font_UnicodeSubset CharSubset (Standard_Utf32Char theUChar)
|
||||
{
|
||||
if (IsCharFromCJK (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_CJK;
|
||||
}
|
||||
else if (IsCharFromKorean (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_Korean;
|
||||
}
|
||||
else if (IsCharFromArabic (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_Arabic;
|
||||
}
|
||||
return Font_UnicodeSubset_Western;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Create uninitialized instance.
|
||||
@@ -53,25 +152,53 @@ public:
|
||||
return myGlyphImg;
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontPath path to the font
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! Initialize the font from the given file path.
|
||||
//! @param theFontPath path to the font
|
||||
//! @param theParams initialization parameters
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontPath,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution);
|
||||
bool Init (const TCollection_AsciiString& theFontPath,
|
||||
const Font_FTFontParams& theParams)
|
||||
{
|
||||
return Init (Handle(NCollection_Buffer)(), theFontPath, theParams);
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! Initialize the font from the given file path or memory buffer.
|
||||
//! @param theData memory to read from, should NOT be freed after initialization!
|
||||
//! when NULL, function will attempt to open theFileName file
|
||||
//! @param theFileName optional path to the font
|
||||
//! @param theParams initialization parameters
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution);
|
||||
Standard_EXPORT bool Init (const Handle(NCollection_Buffer)& theData,
|
||||
const TCollection_AsciiString& theFileName,
|
||||
const Font_FTFontParams& theParams);
|
||||
|
||||
//! Find (using Font_FontMgr) and initialize the font from the given name.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theParams initialization parameters
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||
//! @sa Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||
Standard_Boolean ToUseUnicodeSubsetFallback() const { return myToUseUnicodeSubsetFallback; }
|
||||
|
||||
//! Set if fallback fonts should be used in case if used font does not include symbols from specific Unicode subset.
|
||||
void SetUseUnicodeSubsetFallback (Standard_Boolean theToFallback) { myToUseUnicodeSubsetFallback = theToFallback; }
|
||||
|
||||
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
||||
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
||||
bool IsSingleStrokeFont() const { return myFontParams.IsSingleStrokeFont; }
|
||||
|
||||
//! Set if this font should be rendered as single-stroke (one-line).
|
||||
void SetSingleStrokeFont (bool theIsSingleLine) { myFontParams.IsSingleStrokeFont = theIsSingleLine; }
|
||||
|
||||
//! Return TRUE if italic style should be synthesized; FALSE by default.
|
||||
bool ToSynthesizeItalic() const { return myFontParams.ToSynthesizeItalic; }
|
||||
|
||||
//! Release currently loaded font.
|
||||
Standard_EXPORT virtual void Release();
|
||||
@@ -80,10 +207,10 @@ public:
|
||||
Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
|
||||
|
||||
//! @return maximal glyph width in pixels (rendered to bitmap).
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeX() const;
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeX (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! @return maximal glyph height in pixels (rendered to bitmap).
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeY() const;
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeY (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
|
||||
Standard_EXPORT float Ascender() const;
|
||||
@@ -97,29 +224,46 @@ public:
|
||||
//! Configured point size
|
||||
unsigned int PointSize() const
|
||||
{
|
||||
return myPointSize;
|
||||
return myFontParams.PointSize;
|
||||
}
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Setup glyph scaling along X-axis.
|
||||
//! By default glyphs are not scaled (scaling factor = 1.0)
|
||||
void SetWidthScaling (const float theScaleFactor)
|
||||
{
|
||||
myWidthScaling = theScaleFactor;
|
||||
}
|
||||
|
||||
//! Return TRUE if font contains specified symbol (excluding fallback list).
|
||||
Standard_EXPORT bool HasSymbol (Standard_Utf32Char theUChar) const;
|
||||
|
||||
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered horizontally.
|
||||
Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceX (Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered horizontally.
|
||||
Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUChar the character to be loaded as current one
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceX (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext);
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute vertical advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered vertically.
|
||||
Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute vertical advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered vertically.
|
||||
Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUChar the character to be loaded as current one
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext);
|
||||
|
||||
//! @return glyphs number in this font.
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber() const;
|
||||
//! Return glyphs number in this font.
|
||||
//! @param theToIncludeFallback if TRUE then the number will include fallback list
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! Retrieve glyph bitmap rectangle
|
||||
Standard_EXPORT void GlyphRect (Font_Rect& theRect) const;
|
||||
@@ -131,6 +275,42 @@ public:
|
||||
const Graphic3d_HorizontalTextAlignment theAlignX,
|
||||
const Graphic3d_VerticalTextAlignment theAlignY);
|
||||
|
||||
public:
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontPath path to the font
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @return true on success
|
||||
Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters")
|
||||
bool Init (const NCollection_String& theFontPath,
|
||||
unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
{
|
||||
Font_FTFontParams aParams;
|
||||
aParams.PointSize = thePointSize;
|
||||
aParams.Resolution = theResolution;
|
||||
return Init (theFontPath.ToCString(), aParams);
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @return true on success
|
||||
Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters")
|
||||
bool Init (const NCollection_String& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
{
|
||||
Font_FTFontParams aParams;
|
||||
aParams.PointSize = thePointSize;
|
||||
aParams.Resolution = theResolution;
|
||||
return FindAndInit (theFontName.ToCString(), theFontAspect, aParams);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Convert value to 26.6 fixed-point format for FT library API.
|
||||
@@ -152,24 +332,31 @@ protected:
|
||||
//! Load glyph without rendering it.
|
||||
Standard_EXPORT bool loadGlyph (const Standard_Utf32Char theUChar);
|
||||
|
||||
//! Wrapper for FT_Get_Kerning - retrieve kerning values.
|
||||
Standard_EXPORT bool getKerning (FT_Vector& theKern,
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Initialize fallback font.
|
||||
Standard_EXPORT bool findAndInitFallback (Font_UnicodeSubset theSubset);
|
||||
|
||||
protected:
|
||||
|
||||
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
||||
FT_Face myFTFace; //!< FT face object
|
||||
NCollection_String myFontPath; //!< font path
|
||||
unsigned int myPointSize; //!< point size set by FT_Set_Char_Size
|
||||
int32_t myLoadFlags; //!< default load flags
|
||||
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
||||
Handle(NCollection_Buffer) myBuffer; //!< memory buffer
|
||||
Handle(Font_FTFont) myFallbackFaces[Font_UnicodeSubset_NB]; //!< fallback fonts
|
||||
FT_Face myFTFace; //!< FT face object
|
||||
FT_Face myActiveFTFace; //!< active FT face object (the main of fallback)
|
||||
TCollection_AsciiString myFontPath; //!< font path
|
||||
Font_FTFontParams myFontParams; //!< font initialization parameters
|
||||
Font_FontAspect myFontAspect; //!< font initialization aspect
|
||||
float myWidthScaling; //!< scale glyphs along X-axis
|
||||
int32_t myLoadFlags; //!< default load flags
|
||||
|
||||
Image_PixMap myGlyphImg; //!< cached glyph plane
|
||||
FT_Vector* myKernAdvance; //!< buffer variable
|
||||
Standard_Utf32Char myUChar; //!< currently loaded unicode character
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient) // Type definition
|
||||
Image_PixMap myGlyphImg; //!< cached glyph plane
|
||||
Standard_Utf32Char myUChar; //!< currently loaded unicode character
|
||||
Standard_Boolean myToUseUnicodeSubsetFallback; //!< use default fallback fonts for extended Unicode sub-sets (Korean, CJK, etc.)
|
||||
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient)
|
||||
|
||||
#endif // _Font_FTFont_H__
|
||||
|
@@ -18,11 +18,19 @@
|
||||
//! Specifies aspect of system font.
|
||||
enum Font_FontAspect
|
||||
{
|
||||
Font_FA_Undefined,
|
||||
Font_FA_Regular,
|
||||
Font_FA_Bold,
|
||||
Font_FA_Italic,
|
||||
Font_FA_BoldItalic
|
||||
Font_FontAspect_UNDEFINED = -1, //!< special value reserved for undefined aspect
|
||||
Font_FontAspect_Regular = 0, //!< normal (regular) aspect
|
||||
Font_FontAspect_Bold, //!< bold aspect
|
||||
Font_FontAspect_Italic, //!< italic aspect
|
||||
Font_FontAspect_BoldItalic, //!< bold+italic aspect
|
||||
|
||||
// old aliases
|
||||
Font_FA_Undefined = Font_FontAspect_UNDEFINED,
|
||||
Font_FA_Regular = Font_FontAspect_Regular,
|
||||
Font_FA_Bold = Font_FontAspect_Bold,
|
||||
Font_FA_Italic = Font_FontAspect_Italic,
|
||||
Font_FA_BoldItalic = Font_FontAspect_BoldItalic
|
||||
};
|
||||
enum { Font_FontAspect_NB = Font_FontAspect_BoldItalic + 1 };
|
||||
|
||||
#endif // _Font_FontAspect_HeaderFile
|
||||
|
@@ -13,10 +13,13 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <Font_FontMgr.hxx>
|
||||
|
||||
#include <Font_NameOfFont.hxx>
|
||||
#include <Font_FTLibrary.hxx>
|
||||
#include <Font_SystemFont.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <OSD_Environment.hxx>
|
||||
@@ -28,57 +31,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
|
||||
|
||||
struct Font_FontMgr_FontAliasMapNode
|
||||
{
|
||||
const char * EnumName;
|
||||
const char * FontName;
|
||||
Font_FontAspect FontAspect;
|
||||
};
|
||||
|
||||
static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
|
||||
{
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
|
||||
{ "Courier" , "Courier New" , Font_FA_Regular },
|
||||
{ "Times-Roman" , "Times New Roman", Font_FA_Regular },
|
||||
{ "Times-Bold" , "Times New Roman", Font_FA_Bold },
|
||||
{ "Times-Italic" , "Times New Roman", Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Times New Roman", Font_FA_BoldItalic },
|
||||
{ "ZapfChancery-MediumItalic", "Script" , Font_FA_Regular },
|
||||
{ "Symbol" , "Symbol" , Font_FA_Regular },
|
||||
{ "ZapfDingbats" , "WingDings" , Font_FA_Regular },
|
||||
{ "Rock" , "Arial" , Font_FA_Regular },
|
||||
{ "Iris" , "Lucida Console" , Font_FA_Regular }
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
{ "Courier" , "Droid Sans Mono", Font_FA_Regular },
|
||||
{ "Times-Roman" , "Droid Serif" , Font_FA_Regular },
|
||||
{ "Times-Bold" , "Droid Serif" , Font_FA_Bold },
|
||||
{ "Times-Italic" , "Droid Serif" , Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Droid Serif" , Font_FA_BoldItalic },
|
||||
{ "Arial" , "Roboto" , Font_FA_Regular },
|
||||
|
||||
#else //X11
|
||||
|
||||
{ "Courier" , "Courier" , Font_FA_Regular },
|
||||
{ "Times-Roman" , "Times" , Font_FA_Regular },
|
||||
{ "Times-Bold" , "Times" , Font_FA_Bold },
|
||||
{ "Times-Italic" , "Times" , Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Times" , Font_FA_BoldItalic },
|
||||
{ "Arial" , "Helvetica" , Font_FA_Regular },
|
||||
{ "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1" , Font_FA_Regular },
|
||||
{ "Symbol" , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , Font_FA_Regular },
|
||||
{ "ZapfDingbats" , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , Font_FA_Regular },
|
||||
{ "Rock" , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1" , Font_FA_Regular },
|
||||
{ "Iris" , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1" , Font_FA_Regular }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#define NUM_FONT_ENTRIES (int)(sizeof(Font_FontMgr_MapOfFontsAliases)/sizeof(Font_FontMgr_FontAliasMapNode))
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
@@ -136,6 +88,10 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
|
||||
"/usr/X11/lib/X11/fs/config",
|
||||
NULL
|
||||
};
|
||||
|
||||
// Although fontconfig library can be built for various platforms,
|
||||
// practically it is useful only on desktop Linux distributions, where it is always packaged.
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -215,9 +171,10 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib
|
||||
if (aFontFace->family_name != NULL // skip broken fonts (error in FreeType?)
|
||||
&& FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name);
|
||||
Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath);
|
||||
aResult = new Font_SystemFont (aFontName, anAspect, aFontPath);
|
||||
aResult = new Font_SystemFont (aFontFace->family_name);
|
||||
aResult->SetFontPath (anAspect, theFontPath);
|
||||
// automatically identify some known single-line fonts
|
||||
aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
|
||||
}
|
||||
|
||||
FT_Done_Face (aFontFace);
|
||||
@@ -240,12 +197,147 @@ Handle(Font_FontMgr) Font_FontMgr::GetInstance()
|
||||
return _mgr;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ToUseUnicodeSubsetFallback
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean& Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||
{
|
||||
static Standard_Boolean TheToUseUnicodeSubsetFallback = true;
|
||||
return TheToUseUnicodeSubsetFallback;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : addFontAlias
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_FontMgr::addFontAlias (const TCollection_AsciiString& theAliasName,
|
||||
const Handle(Font_FontAliasSequence)& theAliases,
|
||||
Font_FontAspect theAspect)
|
||||
{
|
||||
if (theAliases.IsNull()
|
||||
|| theAliases->IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(Font_FontAliasSequence) anAliases = theAliases;
|
||||
if (theAspect != Font_FA_Undefined)
|
||||
{
|
||||
anAliases = new Font_FontAliasSequence();
|
||||
for (Font_FontAliasSequence::Iterator anAliasIter (*theAliases); anAliasIter.More(); anAliasIter.Next())
|
||||
{
|
||||
const TCollection_AsciiString& aName = anAliasIter.Value().FontName;
|
||||
anAliases->Append (Font_FontAlias (aName, theAspect));
|
||||
}
|
||||
}
|
||||
|
||||
TCollection_AsciiString anAliasName (theAliasName);
|
||||
anAliasName.LowerCase();
|
||||
myFontAliases.Bind (anAliasName, anAliases);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Font_FontMgr
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Font_FontMgr::Font_FontMgr()
|
||||
: myToTraceAliases (Standard_False)
|
||||
{
|
||||
Handle(Font_FontAliasSequence) aMono = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSerif = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSans = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSymbol = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aScript = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aWinDin = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aCJK = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) anArab = new Font_FontAliasSequence();
|
||||
|
||||
// best matches - pre-installed on Windows, some of them are pre-installed on macOS,
|
||||
// and sometimes them can be found installed on other systems (by user)
|
||||
aMono ->Append (Font_FontAlias ("courier new"));
|
||||
aSerif ->Append (Font_FontAlias ("times new roman"));
|
||||
aSans ->Append (Font_FontAlias ("arial"));
|
||||
aSymbol->Append (Font_FontAlias ("symbol"));
|
||||
aScript->Append (Font_FontAlias ("script"));
|
||||
aWinDin->Append (Font_FontAlias ("wingdings"));
|
||||
anIris ->Append (Font_FontAlias ("lucida console"));
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// Noto font family is usually installed on Android 6+ devices
|
||||
aMono ->Append (Font_FontAlias ("noto mono"));
|
||||
aSerif ->Append (Font_FontAlias ("noto serif"));
|
||||
// Droid font family is usually installed on Android 4+ devices
|
||||
aMono ->Append (Font_FontAlias ("droid sans mono"));
|
||||
aSerif ->Append (Font_FontAlias ("droid serif"));
|
||||
aSans ->Append (Font_FontAlias ("roboto")); // actually DroidSans.ttf
|
||||
#elif !defined(_WIN32) && !defined(__APPLE__) //X11
|
||||
aSerif ->Append (Font_FontAlias ("times"));
|
||||
aSans ->Append (Font_FontAlias ("helvetica"));
|
||||
// GNU FreeFonts family is usually installed on Linux
|
||||
aMono ->Append (Font_FontAlias ("freemono"));
|
||||
aSerif ->Append (Font_FontAlias ("freeserif"));
|
||||
aSans ->Append (Font_FontAlias ("freesans"));
|
||||
// DejaVu font family is usually installed on Linux
|
||||
aMono ->Append (Font_FontAlias ("dejavu sans mono"));
|
||||
aSerif ->Append (Font_FontAlias ("dejavu serif"));
|
||||
aSans ->Append (Font_FontAlias ("dejavu sans"));
|
||||
#endif
|
||||
|
||||
// default CJK (Chinese/Japanese/Korean) fonts
|
||||
aCJK ->Append (Font_FontAlias ("simsun")); // Windows
|
||||
aCJK ->Append (Font_FontAlias ("droid sans fallback")); // Android, Linux
|
||||
aCJK ->Append (Font_FontAlias ("noto sans sc")); // Android
|
||||
|
||||
#if defined(_WIN32)
|
||||
aKorean->Append (Font_FontAlias ("malgun gothic")); // introduced since Vista
|
||||
aKorean->Append (Font_FontAlias ("gulim")); // used on older systems (Windows XP)
|
||||
#elif defined(__APPLE__)
|
||||
aKorean->Append (Font_FontAlias ("applegothic"));
|
||||
aKorean->Append (Font_FontAlias ("stfangsong"));
|
||||
#endif
|
||||
aKorean->Append (Font_FontAlias ("nanumgothic")); // Android, Linux
|
||||
aKorean->Append (Font_FontAlias ("noto sans kr")); // Android
|
||||
aKorean->Append (Font_FontAlias ("nanummyeongjo")); // Linux
|
||||
aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
|
||||
aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
|
||||
|
||||
#if defined(_WIN32)
|
||||
anArab->Append (Font_FontAlias ("times new roman"));
|
||||
#elif defined(__APPLE__)
|
||||
anArab->Append (Font_FontAlias ("decotype naskh"));
|
||||
#elif defined(__ANDROID__)
|
||||
anArab->Append (Font_FontAlias ("droid arabic naskh"));
|
||||
anArab->Append (Font_FontAlias ("noto naskh arabic"));
|
||||
#endif
|
||||
|
||||
addFontAlias ("mono", aMono);
|
||||
addFontAlias ("courier", aMono); // Font_NOF_ASCII_MONO
|
||||
addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
|
||||
addFontAlias ("rock", aSans); // Font_NOF_CARTOGRAPHIC_SIMPLEX
|
||||
addFontAlias ("sansserif", aSans); // Font_NOF_SANS_SERIF
|
||||
addFontAlias ("sans-serif", aSans);
|
||||
addFontAlias ("sans", aSans);
|
||||
addFontAlias ("arial", aSans);
|
||||
addFontAlias ("times", aSerif);
|
||||
addFontAlias ("serif", aSerif); // Font_NOF_SERIF
|
||||
addFontAlias ("times-roman", aSerif); // Font_NOF_ASCII_SIMPLEX
|
||||
addFontAlias ("times-bold", aSerif, Font_FA_Bold); // Font_NOF_ASCII_DUPLEX
|
||||
addFontAlias ("times-italic", aSerif, Font_FA_Italic); // Font_NOF_ASCII_ITALIC_COMPLEX
|
||||
addFontAlias ("times-bolditalic", aSerif, Font_FA_BoldItalic); // Font_NOF_ASCII_ITALIC_TRIPLEX
|
||||
addFontAlias ("symbol", aSymbol); // Font_NOF_GREEK_MONO
|
||||
addFontAlias ("iris", anIris); // Font_NOF_KANJI_MONO
|
||||
addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
|
||||
addFontAlias ("cjk", aCJK); // Font_NOF_CJK
|
||||
addFontAlias ("nsimsun", aCJK);
|
||||
addFontAlias ("arabic", anArab); // Font_NOF_ARABIC
|
||||
addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
|
||||
addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
|
||||
|
||||
myFallbackAlias = aSans;
|
||||
|
||||
InitFontDataBase();
|
||||
}
|
||||
|
||||
@@ -271,39 +363,30 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
|
||||
aFontIter.More(); aFontIter.Next())
|
||||
const Standard_Integer anOldIndex = myFontMap.FindIndex (theFont);
|
||||
if (anOldIndex == 0)
|
||||
{
|
||||
if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFont->FontAspect() != Font_FA_Undefined
|
||||
&& aFontIter.Value()->FontAspect() != theFont->FontAspect())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
|
||||
|| theFont->FontHeight() == aFontIter.Value()->FontHeight())
|
||||
{
|
||||
if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
else if (theToOverride)
|
||||
{
|
||||
myListOfFonts.Remove (aFontIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
myFontMap.Add (theFont);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
myListOfFonts.Append (theFont);
|
||||
Handle(Font_SystemFont) anOldFont = myFontMap.FindKey (anOldIndex);
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
if (anOldFont->FontPath ((Font_FontAspect )anAspectIter).IsEqual (theFont->FontPath ((Font_FontAspect )anAspectIter)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (theToOverride
|
||||
|| !anOldFont->HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
anOldFont->SetFontPath ((Font_FontAspect )anAspectIter, theFont->FontPath ((Font_FontAspect )anAspectIter));
|
||||
}
|
||||
else if (theFont->HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
@@ -313,8 +396,8 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
|
||||
// =======================================================================
|
||||
void Font_FontMgr::InitFontDataBase()
|
||||
{
|
||||
myListOfFonts.Clear();
|
||||
Handle(Font_FTLibrary) aFtLibrary;
|
||||
myFontMap.Clear();
|
||||
Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
|
||||
|
||||
#if defined(OCCT_UWP)
|
||||
// system font files are not accessible
|
||||
@@ -330,8 +413,8 @@ void Font_FontMgr::InitFontDataBase()
|
||||
|
||||
char* aWinDir = new char[aStrLength];
|
||||
GetSystemWindowsDirectoryA (aWinDir, aStrLength);
|
||||
Handle(TCollection_HAsciiString) aFontsDir = new TCollection_HAsciiString (aWinDir);
|
||||
aFontsDir->AssignCat ("\\Fonts\\");
|
||||
TCollection_AsciiString aFontsDir (aWinDir);
|
||||
aFontsDir.AssignCat ("\\Fonts\\");
|
||||
delete[] aWinDir;
|
||||
|
||||
// read fonts list from registry
|
||||
@@ -349,7 +432,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
static const DWORD aBufferSize = 256;
|
||||
char aNameBuff[aBufferSize];
|
||||
char aPathBuff[aBufferSize];
|
||||
@@ -363,25 +445,23 @@ void Font_FontMgr::InitFontDataBase()
|
||||
{
|
||||
aPathBuff[(aPathSize < aBufferSize) ? aPathSize : (aBufferSize - 1)] = '\0'; // ensure string is NULL-terminated
|
||||
|
||||
Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aNameBuff);
|
||||
Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (aPathBuff);
|
||||
if (aFontPath->Search ("\\") == -1)
|
||||
TCollection_AsciiString aFontName (aNameBuff), aFontPath (aPathBuff);
|
||||
if (aFontPath.Search ("\\") == -1)
|
||||
{
|
||||
aFontPath->Insert (1, aFontsDir); // make absolute path
|
||||
aFontPath.Insert (1, aFontsDir); // make absolute path
|
||||
}
|
||||
|
||||
// check file extension is in list of supported
|
||||
const Standard_Integer anExtensionPosition = aFontPath->SearchFromEnd (".") + 1;
|
||||
if (anExtensionPosition > 0 && anExtensionPosition < aFontPath->Length())
|
||||
const Standard_Integer anExtensionPosition = aFontPath.SearchFromEnd (".") + 1;
|
||||
if (anExtensionPosition > 0 && anExtensionPosition < aFontPath.Length())
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontExtension = aFontPath->SubString (anExtensionPosition, aFontPath->Length());
|
||||
aFontExtension->LowerCase();
|
||||
if (aSupportedExtensions.Contains (aFontExtension->String()))
|
||||
TCollection_AsciiString aFontExtension = aFontPath.SubString (anExtensionPosition, aFontPath.Length());
|
||||
aFontExtension.LowerCase();
|
||||
if (aSupportedExtensions.Contains (aFontExtension))
|
||||
{
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
|
||||
if (!aNewFont.IsNull())
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
RegisterFont (aNewFont, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,61 +474,86 @@ void Font_FontMgr::InitFontDataBase()
|
||||
|
||||
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
||||
|
||||
// read fonts directories from font service config file (obsolete)
|
||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||
if (FcConfig* aFcCfg = FcInitLoadConfig())
|
||||
{
|
||||
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
|
||||
OSD_File aFile (aFileOfFontsPath);
|
||||
if (!aFile.Exists())
|
||||
if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
if (!aFile.IsOpen())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Integer aNByte = 256;
|
||||
Standard_Integer aNbyteRead;
|
||||
TCollection_AsciiString aStr; // read string with information
|
||||
while (!aFile.IsAtEnd())
|
||||
{
|
||||
Standard_Integer aLocation = -1;
|
||||
Standard_Integer aPathLocation = -1;
|
||||
|
||||
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
|
||||
aLocation = aStr.Search ("catalogue=");
|
||||
if (aLocation < 0)
|
||||
for (;;)
|
||||
{
|
||||
aLocation = aStr.Search ("catalogue =");
|
||||
}
|
||||
|
||||
aPathLocation = aStr.Search ("/");
|
||||
if (aLocation > 0 && aPathLocation > 0)
|
||||
{
|
||||
aStr = aStr.Split (aPathLocation - 1);
|
||||
TCollection_AsciiString aFontPath;
|
||||
Standard_Integer aPathNumber = 1;
|
||||
do
|
||||
FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
|
||||
if (aFcFolder == NULL)
|
||||
{
|
||||
// Getting directory paths, which can be splitted by "," or ":"
|
||||
aFontPath = aStr.Token (":,", aPathNumber);
|
||||
aFontPath.RightAdjust();
|
||||
if (!aFontPath.IsEmpty())
|
||||
{
|
||||
OSD_Path aPath(aFontPath);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
aPathNumber++;
|
||||
break;
|
||||
}
|
||||
while (!aFontPath.IsEmpty());
|
||||
|
||||
TCollection_AsciiString aPathStr ((const char* )aFcFolder);
|
||||
OSD_Path aPath (aPathStr);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
FcStrListDone (aFcFontDir);
|
||||
}
|
||||
FcConfigDestroy (aFcCfg);
|
||||
}
|
||||
|
||||
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
||||
if (aMapOfFontsDirs.IsEmpty())
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Font_FontMgr, fontconfig library returns an empty folder list", Message_Alarm);
|
||||
|
||||
// read fonts directories from font service config file (obsolete)
|
||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||
{
|
||||
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
|
||||
OSD_File aFile (aFileOfFontsPath);
|
||||
if (!aFile.Exists())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
if (!aFile.IsOpen())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Integer aNByte = 256;
|
||||
Standard_Integer aNbyteRead;
|
||||
TCollection_AsciiString aStr; // read string with information
|
||||
while (!aFile.IsAtEnd())
|
||||
{
|
||||
Standard_Integer aLocation = -1;
|
||||
Standard_Integer aPathLocation = -1;
|
||||
|
||||
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
|
||||
aLocation = aStr.Search ("catalogue=");
|
||||
if (aLocation < 0)
|
||||
{
|
||||
aLocation = aStr.Search ("catalogue =");
|
||||
}
|
||||
|
||||
aPathLocation = aStr.Search ("/");
|
||||
if (aLocation > 0 && aPathLocation > 0)
|
||||
{
|
||||
aStr = aStr.Split (aPathLocation - 1);
|
||||
TCollection_AsciiString aFontPath;
|
||||
Standard_Integer aPathNumber = 1;
|
||||
do
|
||||
{
|
||||
// Getting directory paths, which can be splitted by "," or ":"
|
||||
aFontPath = aStr.Token (":,", aPathNumber);
|
||||
aFontPath.RightAdjust();
|
||||
if (!aFontPath.IsEmpty())
|
||||
{
|
||||
OSD_Path aPath(aFontPath);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
aPathNumber++;
|
||||
}
|
||||
while (!aFontPath.IsEmpty());
|
||||
}
|
||||
}
|
||||
aFile.Close();
|
||||
}
|
||||
aFile.Close();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -468,32 +573,32 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
|
||||
anIter.More(); anIter.Next())
|
||||
{
|
||||
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||
OSD_Path aFolderPath (anIter.Value());
|
||||
for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
|
||||
{
|
||||
OSD_Path aFontFilePath;
|
||||
aFileIter.Values().Path (aFontFilePath);
|
||||
|
||||
TCollection_AsciiString aFontFileName;
|
||||
aFontFilePath.SystemName (aFontFileName);
|
||||
aFontFileName = anIter.Value() + "/" + aFontFileName;
|
||||
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString());
|
||||
if (!aNewFont.IsNull())
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
OSD_File aReadFile (anIter.Value() + "/fonts.dir");
|
||||
if (!aReadFile.Exists())
|
||||
{
|
||||
continue; // invalid fonts directory
|
||||
#endif
|
||||
OSD_Path aFolderPath (anIter.Value());
|
||||
for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
|
||||
{
|
||||
OSD_Path aFontFilePath;
|
||||
aFileIter.Values().Path (aFontFilePath);
|
||||
|
||||
TCollection_AsciiString aFontFileName;
|
||||
aFontFilePath.SystemName (aFontFileName);
|
||||
aFontFileName = anIter.Value() + "/" + aFontFileName;
|
||||
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString()))
|
||||
{
|
||||
RegisterFont (aNewFont, false);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
continue;
|
||||
}
|
||||
|
||||
aReadFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
@@ -536,34 +641,45 @@ void Font_FontMgr::InitFontDataBase()
|
||||
// In current implementation use fonts with ISO-8859-1 coding page.
|
||||
// OCCT not give to manage coding page by means of programm interface.
|
||||
// TODO: make high level interface for choosing necessary coding page.
|
||||
Handle(TCollection_HAsciiString) aXLFD =
|
||||
new TCollection_HAsciiString (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
|
||||
Handle(TCollection_HAsciiString) aFontPath =
|
||||
new TCollection_HAsciiString (anIter.Value().ToCString());
|
||||
if (aFontPath->SearchFromEnd ("/") != aFontPath->Length())
|
||||
TCollection_AsciiString aXLFD (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
|
||||
TCollection_AsciiString aFontPath (anIter.Value().ToCString());
|
||||
if (aFontPath.SearchFromEnd ("/") != aFontPath.Length())
|
||||
{
|
||||
aFontPath->AssignCat ("/");
|
||||
aFontPath.AssignCat ("/");
|
||||
}
|
||||
Handle(TCollection_HAsciiString) aFontFileName =
|
||||
new TCollection_HAsciiString (aLine.SubString (1, anEndOfFileName));
|
||||
aFontPath->AssignCat (aFontFileName);
|
||||
TCollection_AsciiString aFontFileName (aLine.SubString (1, anEndOfFileName));
|
||||
aFontPath.AssignCat (aFontFileName);
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
|
||||
{
|
||||
RegisterFont (aNewFont, false);
|
||||
if (!aXLFD.IsEmpty()
|
||||
&& aXLFD.Search ("-0-0-0-0-") != -1) // ignore non-resizable fonts
|
||||
{
|
||||
const TCollection_AsciiString anXName = aXLFD.Token ("-", 2);
|
||||
Font_FontAspect anXAspect = Font_FA_Regular;
|
||||
if (aXLFD.Token ("-", 3).IsEqual ("bold")
|
||||
&& (aXLFD.Token ("-", 4).IsEqual ("i")
|
||||
|| aXLFD.Token ("-", 4).IsEqual ("o")))
|
||||
{
|
||||
anXAspect = Font_FA_BoldItalic;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
|
||||
{
|
||||
anXAspect = Font_FA_Bold;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 4).IsEqual ("i")
|
||||
|| aXLFD.Token ("-", 4).IsEqual ("o"))
|
||||
{
|
||||
anXAspect = Font_FA_Italic;
|
||||
}
|
||||
|
||||
Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (aXLFD, aFontPath);
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
|
||||
|
||||
if (aNewFontFromXLFD->IsValid() && !aNewFont.IsNull() &&
|
||||
!aNewFont->IsEqual (aNewFontFromXLFD))
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
myListOfFonts.Append (aNewFontFromXLFD);
|
||||
}
|
||||
else if (!aNewFont.IsNull())
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
}
|
||||
else if (aNewFontFromXLFD->IsValid())
|
||||
{
|
||||
myListOfFonts.Append (aNewFontFromXLFD);
|
||||
Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (anXName);
|
||||
aNewFontFromXLFD->SetFontPath (anXAspect, aFontPath);
|
||||
if (!aNewFont->IsEqual (aNewFontFromXLFD))
|
||||
{
|
||||
RegisterFont (aNewFontFromXLFD, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,15 +689,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
#endif
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetAvailableFonts
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
|
||||
{
|
||||
return myListOfFonts;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetAvailableFontsNames
|
||||
// purpose :
|
||||
@@ -589,9 +696,11 @@ const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
|
||||
void Font_FontMgr::GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const
|
||||
{
|
||||
theFontsNames.Clear();
|
||||
for (Font_NListOfSystemFont::Iterator anIter(myListOfFonts); anIter.More(); anIter.Next())
|
||||
for (NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>::Iterator aFontIter (myFontMap);
|
||||
aFontIter.More(); aFontIter.Next())
|
||||
{
|
||||
theFontsNames.Append (anIter.Value()->FontName());
|
||||
const Handle(Font_SystemFont)& aFont = aFontIter.Value();
|
||||
theFontsNames.Append (new TCollection_HAsciiString(aFont->FontName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,101 +712,180 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Integer theFontSize) const
|
||||
{
|
||||
if ( (theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
|
||||
if ((theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
|
||||
{
|
||||
return NULL;
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
|
||||
aFontsIterator.More(); aFontsIterator.Next())
|
||||
Handle(Font_SystemFont) aFont = myFontMap.Find (theFontName->String());
|
||||
return (aFont.IsNull()
|
||||
|| theFontAspect == Font_FontAspect_UNDEFINED
|
||||
|| aFont->HasFontAspect (theFontAspect))
|
||||
? aFont
|
||||
: Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& theFontName) const
|
||||
{
|
||||
return myFontMap.Find (theFontName);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FindFallbackFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||
Font_FontAspect theFontAspect) const
|
||||
{
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
switch (theSubset)
|
||||
{
|
||||
if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFontAspect != Font_FA_Undefined && aFontsIterator.Value()->FontAspect() != theFontAspect)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFontSize == -1 || aFontsIterator.Value()->FontHeight() == -1 ||
|
||||
theFontSize == aFontsIterator.Value()->FontHeight())
|
||||
{
|
||||
return aFontsIterator.Value();
|
||||
}
|
||||
case Font_UnicodeSubset_Western: return FindFont (Font_NOF_SANS_SERIF, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_Korean: return FindFont (Font_NOF_KOREAN, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_CJK: return FindFont (Font_NOF_CJK, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_Arabic: return FindFont (Font_NOF_ARABIC, Font_StrictLevel_Aliases, aFontAspect);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FindFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFont (const Handle(TCollection_HAsciiString)& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Integer theFontSize) const
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_StrictLevel theStrictLevel,
|
||||
Font_FontAspect& theFontAspect) const
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontName = theFontName;
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
Standard_Integer aFontSize = theFontSize;
|
||||
|
||||
Handle(Font_SystemFont) aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
TCollection_AsciiString aFontName (theFontName);
|
||||
aFontName.LowerCase();
|
||||
Handle(Font_SystemFont) aFont = myFontMap.Find (aFontName);
|
||||
if (!aFont.IsNull()
|
||||
|| theStrictLevel == Font_StrictLevel_Strict)
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
|
||||
// Trying to use font names mapping
|
||||
for (Standard_Integer anIter = 0; anIter < NUM_FONT_ENTRIES; ++anIter)
|
||||
for (int aPass = 0; aPass < 2; ++aPass)
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontAlias =
|
||||
new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].EnumName);
|
||||
|
||||
if (aFontAlias->IsSameString (aFontName, Standard_False))
|
||||
Handle(Font_FontAliasSequence) anAliases;
|
||||
if (aPass == 0)
|
||||
{
|
||||
aFontName = new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].FontName);
|
||||
aFontAspect = Font_FontMgr_MapOfFontsAliases[anIter].FontAspect;
|
||||
break;
|
||||
myFontAliases.Find (aFontName, anAliases);
|
||||
}
|
||||
else if (theStrictLevel == Font_StrictLevel_Any)
|
||||
{
|
||||
anAliases = myFallbackAlias;
|
||||
}
|
||||
|
||||
if (anAliases.IsNull()
|
||||
|| anAliases->IsEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isAliasUsed = false, isBestAlias = false;
|
||||
for (Font_FontAliasSequence::Iterator anAliasIter (*anAliases); anAliasIter.More(); anAliasIter.Next())
|
||||
{
|
||||
const Font_FontAlias& anAlias = anAliasIter.Value();
|
||||
if (Handle(Font_SystemFont) aFont2 = myFontMap.Find (anAlias.FontName))
|
||||
{
|
||||
if (aFont.IsNull())
|
||||
{
|
||||
aFont = aFont2;
|
||||
isAliasUsed = true;
|
||||
}
|
||||
|
||||
if ((anAlias.FontAspect != Font_FontAspect_UNDEFINED
|
||||
&& aFont2->HasFontAspect (anAlias.FontAspect)))
|
||||
{
|
||||
// special case - alias refers to styled font (e.g. "times-bold")
|
||||
isBestAlias = true;
|
||||
theFontAspect = anAlias.FontAspect;
|
||||
break;
|
||||
}
|
||||
else if (anAlias.FontAspect == Font_FontAspect_UNDEFINED
|
||||
&& (theFontAspect == Font_FontAspect_UNDEFINED
|
||||
|| aFont2->HasFontAspect (theFontAspect)))
|
||||
{
|
||||
isBestAlias = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aPass == 0)
|
||||
{
|
||||
if (isAliasUsed && myToTraceAliases)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, using font alias '") + aFont->FontName() + "'"
|
||||
" instead of requested '" + theFontName +"'", Message_Trace);
|
||||
}
|
||||
if (isBestAlias)
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
else if (!aFont.IsNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check font family alias with specified font aspect
|
||||
if (theFontAspect != Font_FA_Undefined
|
||||
&& theFontAspect != Font_FA_Regular
|
||||
&& theFontAspect != aFontAspect)
|
||||
if (aFont.IsNull()
|
||||
&& theStrictLevel == Font_StrictLevel_Any)
|
||||
{
|
||||
aFont = GetFont (aFontName, theFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
// try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
|
||||
aFont = myFontMap.Find (TCollection_AsciiString());
|
||||
}
|
||||
if (aFont.IsNull())
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, error: unable to find any font!", Message_Fail));
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
// check font alias with aspect in the name
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
if ((theFontAspect != Font_FA_Undefined
|
||||
&& !aFont->HasFontAspect (theFontAspect))
|
||||
|| (!aFontName.IsEmpty()
|
||||
&& !aFontName.IsEqual (aFont->FontKey())))
|
||||
{
|
||||
return aFont;
|
||||
TCollection_AsciiString aDesc = TCollection_AsciiString() + "'" + theFontName + "'"
|
||||
+ TCollection_AsciiString() + " [" + Font_FontMgr::FontAspectToString (theFontAspect) + "]";
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, warning: unable to find font ")
|
||||
+ aDesc + "; " + aFont->ToString() + " is used instead");
|
||||
}
|
||||
|
||||
// Requested family name not found -> search for any font family with given aspect and height
|
||||
aFontName = new TCollection_HAsciiString ("");
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
|
||||
// The last resort: trying to use ANY font available in the system
|
||||
aFontAspect = Font_FA_Undefined;
|
||||
aFontSize = -1;
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
|
||||
return NULL; // Fonts are not found in the system.
|
||||
return aFont;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Font_FontMap::Find
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::Font_FontMap::Find (const TCollection_AsciiString& theFontName) const
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
else if (theFontName.IsEmpty())
|
||||
{
|
||||
return FindKey (1); // return any font
|
||||
}
|
||||
|
||||
TCollection_AsciiString aFontName (theFontName);
|
||||
aFontName.LowerCase();
|
||||
for (IndexedMapNode* aNodeIter = (IndexedMapNode* )myData1[::HashCode (aFontName, NbBuckets())];
|
||||
aNodeIter != NULL; aNodeIter = (IndexedMapNode* )aNodeIter->Next())
|
||||
{
|
||||
const Handle(Font_SystemFont)& aKey = aNodeIter->Key1();
|
||||
if (aKey->FontKey().IsEqual (aFontName))
|
||||
{
|
||||
return aKey;
|
||||
}
|
||||
}
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
@@ -17,33 +17,67 @@
|
||||
#define _Font_FontMgr_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Font_NListOfSystemFont.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <TColStd_SequenceOfHAsciiString.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Font_NListOfSystemFont.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <TColStd_SequenceOfHAsciiString.hxx>
|
||||
|
||||
class Font_SystemFont;
|
||||
class TCollection_HAsciiString;
|
||||
|
||||
|
||||
class Font_FontMgr;
|
||||
DEFINE_STANDARD_HANDLE(Font_FontMgr, Standard_Transient)
|
||||
|
||||
//! Collects and provides information about available fonts in system.
|
||||
class Font_FontMgr : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FontMgr, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Return global instance of font manager.
|
||||
Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
|
||||
|
||||
//! Return font aspect as string.
|
||||
static const char* FontAspectToString (Font_FontAspect theAspect)
|
||||
{
|
||||
switch (theAspect)
|
||||
{
|
||||
case Font_FontAspect_UNDEFINED: return "undefined";
|
||||
case Font_FontAspect_Regular: return "regular";
|
||||
case Font_FontAspect_Bold: return "bold";
|
||||
case Font_FontAspect_Italic: return "italic";
|
||||
case Font_FontAspect_BoldItalic: return "bold-italic";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||
Standard_EXPORT static Standard_Boolean& ToUseUnicodeSubsetFallback();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
|
||||
|
||||
Standard_EXPORT const Font_NListOfSystemFont& GetAvailableFonts() const;
|
||||
|
||||
//! Return the list of available fonts.
|
||||
void AvailableFonts (Font_NListOfSystemFont& theList) const
|
||||
{
|
||||
for (Font_FontMap::Iterator aFontIter (myFontMap); aFontIter.More(); aFontIter.Next())
|
||||
{
|
||||
theList.Append (aFontIter.Value());
|
||||
}
|
||||
}
|
||||
|
||||
//! Return the list of available fonts.
|
||||
Font_NListOfSystemFont GetAvailableFonts() const
|
||||
{
|
||||
Font_NListOfSystemFont aList;
|
||||
AvailableFonts (aList);
|
||||
return aList;
|
||||
}
|
||||
|
||||
//! Returns sequence of available fonts names
|
||||
Standard_EXPORT void GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const;
|
||||
|
||||
@@ -52,51 +86,119 @@ public:
|
||||
//! If theFontAspect is Font_FA_Undefined returned font can have any FontAspect.
|
||||
//! If theFontSize is "-1" returned font can have any FontSize.
|
||||
Standard_EXPORT Handle(Font_SystemFont) GetFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
|
||||
|
||||
|
||||
//! Returns font that match given name or NULL if such font family is NOT registered.
|
||||
//! Note that unlike FindFont(), this method ignores font aliases and does not look for fall-back.
|
||||
Standard_EXPORT Handle(Font_SystemFont) GetFont (const TCollection_AsciiString& theFontName) const;
|
||||
|
||||
//! Tries to find font by given parameters.
|
||||
//! If the specified font is not found tries to use font names mapping.
|
||||
//! If the requested family name not found -> search for any font family
|
||||
//! with given aspect and height. If the font is still not found, returns
|
||||
//! any font available in the system. Returns NULL in case when the fonts
|
||||
//! are not found in the system.
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
|
||||
|
||||
//! If the requested family name not found -> search for any font family with given aspect and height.
|
||||
//! If the font is still not found, returns any font available in the system.
|
||||
//! Returns NULL in case when the fonts are not found in the system.
|
||||
//! @param theFontName [in] font family to find or alias name
|
||||
//! @param theStrictLevel [in] search strict level for using aliases and fallback
|
||||
//! @param theFontAspect [in] [out] font aspect to find (considered only if family name is not found);
|
||||
//! can be modified if specified font alias refers to another style (compatibility with obsolete aliases)
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_StrictLevel theStrictLevel,
|
||||
Font_FontAspect& theFontAspect) const;
|
||||
|
||||
//! Tries to find font by given parameters.
|
||||
Handle(Font_SystemFont) FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect& theFontAspect) const
|
||||
{
|
||||
return FindFont (theFontName, Font_StrictLevel_Any, theFontAspect);
|
||||
}
|
||||
|
||||
//! Tries to find fallback font for specified Unicode subset.
|
||||
//! Returns NULL in case when fallback font is not found in the system.
|
||||
//! @param theSubset [in] Unicode subset
|
||||
//! @param theFontAspect [in] font aspect to find
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||
Font_FontAspect theFontAspect) const;
|
||||
|
||||
//! Read font file and retrieve information from it.
|
||||
Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
|
||||
|
||||
//! Register new font.
|
||||
//! If there is existing entity with the same name and properties but different path
|
||||
//! then font will will be overridden or ignored depending on theToOverride flag.
|
||||
//! then font will be overridden or ignored depending on theToOverride flag.
|
||||
Standard_EXPORT Standard_Boolean RegisterFont (const Handle(Font_SystemFont)& theFont, const Standard_Boolean theToOverride);
|
||||
|
||||
//! Return flag for tracing font aliases usage via Message_Trace messages; TRUE by default.
|
||||
Standard_Boolean ToTraceAliases() const { return myToTraceAliases; }
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
//! Set flag for tracing font alias usage; useful to trace which fonts are actually used.
|
||||
//! Can be disabled to avoid redundant messages with Message_Trace level.
|
||||
void SetTraceAliases (Standard_Boolean theToTrace) { myToTraceAliases = theToTrace; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//! Creates empty font object
|
||||
//! Creates empty font manager object
|
||||
Standard_EXPORT Font_FontMgr();
|
||||
|
||||
//! Collects available fonts paths.
|
||||
Standard_EXPORT void InitFontDataBase();
|
||||
|
||||
Font_NListOfSystemFont myListOfFonts;
|
||||
private:
|
||||
|
||||
//! Map storing registered fonts.
|
||||
class Font_FontMap : public NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>
|
||||
{
|
||||
public:
|
||||
//! Empty constructor.
|
||||
Font_FontMap() {}
|
||||
|
||||
//! Try finding font with specified parameters or the closest one.
|
||||
//! @param theFontName [in] font family to find (or empty string if family name can be ignored)
|
||||
//! @return best match font or NULL if not found
|
||||
Handle(Font_SystemFont) Find (const TCollection_AsciiString& theFontName) const;
|
||||
|
||||
public:
|
||||
|
||||
//! Hash value, for Map interface.
|
||||
//! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
|
||||
static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
|
||||
const Standard_Integer theUpper)
|
||||
{
|
||||
return ::HashCode (theFont->FontKey(), theUpper);
|
||||
}
|
||||
|
||||
//! Matching two instances, for Map interface.
|
||||
static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
|
||||
const Handle(Font_SystemFont)& theFont2)
|
||||
{
|
||||
return theFont1->IsEqual (theFont2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//! Structure defining font alias.
|
||||
struct Font_FontAlias
|
||||
{
|
||||
TCollection_AsciiString FontName;
|
||||
Font_FontAspect FontAspect;
|
||||
|
||||
Font_FontAlias (const TCollection_AsciiString& theFontName, Font_FontAspect theFontAspect = Font_FontAspect_UNDEFINED) : FontName (theFontName), FontAspect (theFontAspect) {}
|
||||
Font_FontAlias() : FontAspect (Font_FontAspect_UNDEFINED) {}
|
||||
};
|
||||
|
||||
//! Sequence of font aliases.
|
||||
typedef NCollection_Shared< NCollection_Sequence<Font_FontAlias> > Font_FontAliasSequence;
|
||||
|
||||
//! Register font alias.
|
||||
void addFontAlias (const TCollection_AsciiString& theAliasName,
|
||||
const Handle(Font_FontAliasSequence)& theAliases,
|
||||
Font_FontAspect theAspect = Font_FontAspect_UNDEFINED);
|
||||
|
||||
private:
|
||||
|
||||
Font_FontMap myFontMap;
|
||||
NCollection_DataMap<TCollection_AsciiString, Handle(Font_FontAliasSequence)> myFontAliases;
|
||||
Handle(Font_FontAliasSequence) myFallbackAlias;
|
||||
Standard_Boolean myToTraceAliases;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _Font_FontMgr_HeaderFile
|
||||
|
@@ -13,7 +13,14 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#define Font_NOF_ASCII_MONO "Courier"
|
||||
#define Font_NOF_MONOSPACE "monospace"
|
||||
#define Font_NOF_SERIF "serif"
|
||||
#define Font_NOF_SANS_SERIF "sans-serif"
|
||||
#define Font_NOF_CJK "cjk" // Font_UnicodeSubset_CJK
|
||||
#define Font_NOF_KOREAN "korean" // Font_UnicodeSubset_Korean
|
||||
#define Font_NOF_ARABIC "arabic" // Font_UnicodeSubset_Arabic
|
||||
|
||||
#define Font_NOF_ASCII_MONO "Courier"
|
||||
#define Font_NOF_ASCII_SIMPLEX "Times-Roman"
|
||||
#define Font_NOF_ASCII_COMPLEX "Times-Roman"
|
||||
#define Font_NOF_ASCII_DUPLEX "Times-Bold"
|
||||
|
@@ -1,7 +1,4 @@
|
||||
// Created on: 1992-08-18
|
||||
// Created by: Herve LEGRAND
|
||||
// Copyright (c) 1992-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
@@ -14,7 +11,15 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Font_StrictLevel_HeaderFile
|
||||
#define _Font_StrictLevel_HeaderFile
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <HLRBRep_SLPropsATool.hxx>
|
||||
//! Enumeration defining font search restrictions.
|
||||
enum Font_StrictLevel
|
||||
{
|
||||
Font_StrictLevel_Strict, //!< search only for exact font
|
||||
Font_StrictLevel_Aliases, //!< search for exact font match and for aliases (ignore global fallback)
|
||||
Font_StrictLevel_Any, //!< search for any font, including global fallback
|
||||
};
|
||||
|
||||
#endif // _Font_StrictLevel_HeaderFile
|
@@ -13,126 +13,96 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
// Updated:
|
||||
|
||||
#include <Font_SystemFont.hxx>
|
||||
|
||||
#include <Font_FontMgr.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
|
||||
|
||||
Font_SystemFont::Font_SystemFont():
|
||||
MyFontName(),
|
||||
MyFontAspect(Font_FA_Undefined),
|
||||
MyFaceSize(-1),
|
||||
MyVerification(Standard_False)
|
||||
// =======================================================================
|
||||
// function : Font_SystemFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Font_SystemFont::Font_SystemFont (const TCollection_AsciiString& theFontName)
|
||||
: myFontKey (theFontName),
|
||||
myFontName (theFontName),
|
||||
myIsSingleLine (Standard_False)
|
||||
{
|
||||
if (theFontName.IsEmpty()) { throw Standard_ProgramError ("Font_SystemFont constructor called with empty font name"); }
|
||||
myFontKey.LowerCase();
|
||||
}
|
||||
|
||||
Font_SystemFont::Font_SystemFont( const Handle(TCollection_HAsciiString)& FontName,
|
||||
const Font_FontAspect FontAspect,
|
||||
const Handle(TCollection_HAsciiString)& FilePath ):
|
||||
MyFontName(FontName),
|
||||
MyFontAspect(FontAspect),
|
||||
MyFaceSize(-1),
|
||||
MyFilePath(FilePath),
|
||||
MyVerification(Standard_True)
|
||||
// =======================================================================
|
||||
// function : SetFontPath
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_SystemFont::SetFontPath (Font_FontAspect theAspect,
|
||||
const TCollection_AsciiString& thePath)
|
||||
{
|
||||
|
||||
if (theAspect == Font_FontAspect_UNDEFINED) { throw Standard_ProgramError ("Font_SystemFont::SetFontPath() called with UNDEFINED aspect"); }
|
||||
myFilePaths[theAspect] = thePath;
|
||||
}
|
||||
|
||||
Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
|
||||
const Handle(TCollection_HAsciiString)& theFilePath) :
|
||||
MyFontAspect(Font_FA_Regular),
|
||||
MyFaceSize(-1),
|
||||
MyFilePath(theFilePath)
|
||||
// =======================================================================
|
||||
// function : IsEqual
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const
|
||||
{
|
||||
MyVerification = Standard_True;
|
||||
if (theXLFD.IsNull())
|
||||
{
|
||||
MyVerification = Standard_False; // empty font description handler
|
||||
}
|
||||
if (theXLFD->IsEmpty())
|
||||
{
|
||||
MyVerification = Standard_False; // empty font description
|
||||
}
|
||||
return theOtherFont.get() == this
|
||||
|| myFontKey.IsEqual (theOtherFont->myFontKey);
|
||||
}
|
||||
|
||||
if (MyVerification)
|
||||
{
|
||||
MyFontName = theXLFD->Token ("-", 2);
|
||||
TCollection_AsciiString aXLFD (theXLFD->ToCString());
|
||||
// =======================================================================
|
||||
// function : ToString
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Font_SystemFont::ToString() const
|
||||
{
|
||||
TCollection_AsciiString aDesc;
|
||||
aDesc += TCollection_AsciiString() + "'" + myFontName + "'";
|
||||
|
||||
// Getting font size for fixed size fonts
|
||||
if (aXLFD.Search ("-0-0-0-0-") >= 0)
|
||||
MyFaceSize = -1; // Scalable font
|
||||
bool isFirstAspect = true;
|
||||
aDesc += " [aspects: ";
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isFirstAspect)
|
||||
{
|
||||
aDesc += ",";
|
||||
}
|
||||
else
|
||||
//TODO catch exeption
|
||||
MyFaceSize = aXLFD.Token ("-", 7).IntegerValue();
|
||||
|
||||
// Detect font aspect
|
||||
if (aXLFD.Token ("-", 3).IsEqual ("bold") &&
|
||||
(aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o")))
|
||||
{
|
||||
MyFontAspect = Font_FA_BoldItalic;
|
||||
isFirstAspect = false;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
|
||||
aDesc += Font_FontMgr::FontAspectToString ((Font_FontAspect )anAspectIter);
|
||||
}
|
||||
aDesc += "]";
|
||||
|
||||
isFirstAspect = true;
|
||||
aDesc += " [paths: ";
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
MyFontAspect = Font_FA_Bold;
|
||||
continue;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o"))
|
||||
|
||||
if (!isFirstAspect)
|
||||
{
|
||||
MyFontAspect = Font_FA_Italic;
|
||||
aDesc += ";";
|
||||
}
|
||||
else
|
||||
{
|
||||
isFirstAspect = false;
|
||||
}
|
||||
aDesc += FontPath ((Font_FontAspect )anAspectIter);
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Font_SystemFont::IsValid() const{
|
||||
if ( !MyVerification)
|
||||
return Standard_False;
|
||||
|
||||
if ( MyFontAspect == Font_FA_Undefined )
|
||||
return Standard_False;
|
||||
|
||||
if ( MyFontName->IsEmpty() || !MyFontName->IsAscii() )
|
||||
return Standard_False;
|
||||
|
||||
OSD_Path path;
|
||||
return path.IsValid( MyFilePath->String() );
|
||||
}
|
||||
|
||||
Handle(TCollection_HAsciiString) Font_SystemFont::FontPath() const{
|
||||
return MyFilePath;
|
||||
}
|
||||
|
||||
Handle(TCollection_HAsciiString) Font_SystemFont::FontName() const{
|
||||
return MyFontName;
|
||||
}
|
||||
|
||||
Font_FontAspect Font_SystemFont::FontAspect() const{
|
||||
return MyFontAspect;
|
||||
}
|
||||
|
||||
Standard_Integer Font_SystemFont::FontHeight() const {
|
||||
return MyFaceSize;
|
||||
}
|
||||
|
||||
Standard_Boolean Font_SystemFont::IsEqual(const Handle(Font_SystemFont)& theOtherFont) const
|
||||
{
|
||||
if (!MyFontName->IsSameString (theOtherFont->FontName(), Standard_False))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (MyFontAspect != theOtherFont->FontAspect())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (MyFaceSize != theOtherFont->FontHeight())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
aDesc += "]";
|
||||
return aDesc;
|
||||
}
|
||||
|
@@ -16,85 +16,123 @@
|
||||
#ifndef _Font_SystemFont_HeaderFile
|
||||
#define _Font_SystemFont_HeaderFile
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
class TCollection_HAsciiString;
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
|
||||
class Font_SystemFont;
|
||||
DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
|
||||
|
||||
//! Structure for store of Font System Information
|
||||
//! This class stores information about the font, which is merely a file path and cached metadata about the font.
|
||||
class Font_SystemFont : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Creates a new font object.
|
||||
Standard_EXPORT Font_SystemFont (const TCollection_AsciiString& theFontName);
|
||||
|
||||
//! Returns font family name (lower-cased).
|
||||
const TCollection_AsciiString& FontKey() const { return myFontKey; }
|
||||
|
||||
//! Returns font family name.
|
||||
const TCollection_AsciiString& FontName() const { return myFontName; }
|
||||
|
||||
//! Returns font file path.
|
||||
const TCollection_AsciiString& FontPath (Font_FontAspect theAspect) const
|
||||
{
|
||||
return myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
//! Sets font file path for specific aspect.
|
||||
Standard_EXPORT void SetFontPath (Font_FontAspect theAspect,
|
||||
const TCollection_AsciiString& thePath);
|
||||
|
||||
//! Returns TRUE if dedicated file for specified font aspect has been defined.
|
||||
bool HasFontAspect (Font_FontAspect theAspect) const
|
||||
{
|
||||
return !myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular].IsEmpty();
|
||||
}
|
||||
|
||||
//! Returns any defined font file path.
|
||||
const TCollection_AsciiString& FontPathAny (Font_FontAspect theAspect,
|
||||
bool& theToSynthesizeItalic) const
|
||||
{
|
||||
const TCollection_AsciiString& aPath = myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
|
||||
if (!aPath.IsEmpty())
|
||||
{
|
||||
return aPath;
|
||||
}
|
||||
|
||||
if (theAspect == Font_FontAspect_Italic
|
||||
|| theAspect == Font_FontAspect_BoldItalic)
|
||||
{
|
||||
if (theAspect == Font_FontAspect_BoldItalic
|
||||
&& !myFilePaths[Font_FontAspect_Bold].IsEmpty())
|
||||
{
|
||||
theToSynthesizeItalic = true;
|
||||
return myFilePaths[Font_FontAspect_Bold];
|
||||
}
|
||||
else if (!myFilePaths[Font_FontAspect_Regular].IsEmpty())
|
||||
{
|
||||
theToSynthesizeItalic = true;
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
}
|
||||
|
||||
if (!myFilePaths[Font_FontAspect_Regular].IsEmpty())
|
||||
{
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
if (!myFilePaths[anAspectIter].IsEmpty())
|
||||
{
|
||||
return myFilePaths[anAspectIter];
|
||||
}
|
||||
}
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
//! Return true if the FontName, FontAspect and FontSize are the same.
|
||||
Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
|
||||
|
||||
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
||||
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
||||
Standard_Boolean IsSingleStrokeFont() const { return myIsSingleLine; }
|
||||
|
||||
//! Set if this font should be rendered as single-stroke (one-line).
|
||||
void SetSingleStrokeFont (Standard_Boolean theIsSingleLine) { myIsSingleLine = theIsSingleLine; }
|
||||
|
||||
//! Format font description.
|
||||
Standard_EXPORT TCollection_AsciiString ToString() const;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//! Creates empty font object
|
||||
Standard_EXPORT Font_SystemFont();
|
||||
|
||||
//! Creates Font object initialized with <FontName> as name
|
||||
//! <FontAspect>.... TODO
|
||||
Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Handle(TCollection_HAsciiString)& theFilePath);
|
||||
|
||||
//! Creates Font object and initialize class fields with
|
||||
//! values taken from XLFD (X Logical Font Description)
|
||||
Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theXLFD, const Handle(TCollection_HAsciiString)& theFilePath);
|
||||
|
||||
//! Returns font family name
|
||||
Standard_EXPORT Handle(TCollection_HAsciiString) FontName() const;
|
||||
|
||||
//! Returns font file path
|
||||
//! Level: Public
|
||||
Standard_EXPORT Handle(TCollection_HAsciiString) FontPath() const;
|
||||
|
||||
//! Returns font aspect
|
||||
//! Level: Public
|
||||
Standard_EXPORT Font_FontAspect FontAspect() const;
|
||||
|
||||
//! Returns font height
|
||||
//! If returned value is equal -1 it means that font is resizable
|
||||
//! Level: Public
|
||||
Standard_EXPORT Standard_Integer FontHeight() const;
|
||||
|
||||
Standard_EXPORT Standard_Boolean IsValid() const;
|
||||
|
||||
//! Return true if the FontName, FontAspect and FontSize are the same.
|
||||
//! Level: Public
|
||||
Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//! Hash value, for Map interface.
|
||||
//! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
|
||||
static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
|
||||
const Standard_Integer theUpper)
|
||||
{
|
||||
return ::HashCode (theFont->FontKey(), theUpper);
|
||||
}
|
||||
|
||||
//! Matching two instances, for Map interface.
|
||||
static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
|
||||
const Handle(Font_SystemFont)& theFont2)
|
||||
{
|
||||
return theFont1->IsEqual (theFont2);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Handle(TCollection_HAsciiString) MyFontName;
|
||||
Font_FontAspect MyFontAspect;
|
||||
Standard_Integer MyFaceSize;
|
||||
Handle(TCollection_HAsciiString) MyFilePath;
|
||||
Standard_Boolean MyVerification;
|
||||
|
||||
TCollection_AsciiString myFilePaths[Font_FontAspect_NB]; //!< paths to the font file
|
||||
TCollection_AsciiString myFontKey; //!< font family name, lower cased
|
||||
TCollection_AsciiString myFontName; //!< font family name
|
||||
Standard_Boolean myIsSingleLine; //!< single stroke font flag, FALSE by default
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
|
||||
|
||||
#endif // _Font_SystemFont_HeaderFile
|
||||
|
28
src/Font/Font_UnicodeSubset.hxx
Normal file
28
src/Font/Font_UnicodeSubset.hxx
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2019 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 _Font_UnicodeSubset_HeaderFile
|
||||
#define _Font_UnicodeSubset_HeaderFile
|
||||
|
||||
//! Enumeration defining Unicode subsets.
|
||||
enum Font_UnicodeSubset
|
||||
{
|
||||
Font_UnicodeSubset_Western, //!< western letters
|
||||
Font_UnicodeSubset_Korean, //!< modern Korean letters
|
||||
Font_UnicodeSubset_CJK, //!< Chinese characters (Chinese, Japanese, Korean and Vietnam)
|
||||
Font_UnicodeSubset_Arabic, //!< Arabic characters
|
||||
};
|
||||
|
||||
enum { Font_UnicodeSubset_NB = Font_UnicodeSubset_Arabic };
|
||||
|
||||
#endif // _Font_UnicodeSubset_HeaderFile
|
@@ -191,7 +191,7 @@ pararg2(1,aNbSolMAX)
|
||||
Geom2dInt_TheIntConicCurveOfGInter Intp(Line,D1,C2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -375,7 +375,7 @@ pararg2(1,aNbSolMAX)
|
||||
Intp.Perform(Circ,D1,C2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -507,7 +507,7 @@ pararg2(1,aNbSolMAX)
|
||||
Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length(); i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -853,7 +853,7 @@ pararg2(1,aNbSolMAX)
|
||||
if (!Intp.IsEmpty()) {
|
||||
const Standard_Real aSQApproxTol = Precision::Approximation() *
|
||||
Precision::Approximation();
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++)
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++)
|
||||
{
|
||||
Standard_Real aU0 = Intp.Point(i).ParamOnFirst();
|
||||
Standard_Real aV0 = Intp.Point(i).ParamOnSecond();
|
||||
|
@@ -365,7 +365,7 @@ static Standard_Integer xdistcs(Draw_Interpretor& di, Standard_Integer n, const
|
||||
// report error or warning if distance is greater than tolerance
|
||||
if (aD > anErrTol)
|
||||
{
|
||||
di << "Error :";
|
||||
di << "Error in " << a[1] << ":";
|
||||
}
|
||||
else if (aD > aWarnTol)
|
||||
{
|
||||
|
@@ -24,7 +24,9 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AspectLine3d, Standard_Transient)
|
||||
Graphic3d_AspectLine3d::Graphic3d_AspectLine3d()
|
||||
: myColor (Quantity_NOC_YELLOW),
|
||||
myType (Aspect_TOL_SOLID),
|
||||
myWidth (1.0f)
|
||||
myWidth (1.0f),
|
||||
myLineFactor (1),
|
||||
myLinePattern (0xFFFF)
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -38,7 +40,9 @@ Graphic3d_AspectLine3d::Graphic3d_AspectLine3d (const Quantity_Color& theColor
|
||||
const Standard_Real theWidth)
|
||||
: myColor (theColor),
|
||||
myType (theType),
|
||||
myWidth ((float )theWidth)
|
||||
myWidth ((float )theWidth),
|
||||
myLineFactor (1),
|
||||
myLinePattern (DefaultLinePatternForType (theType))
|
||||
{
|
||||
if (myWidth <= 0.0f)
|
||||
{
|
||||
|
@@ -61,7 +61,64 @@ public:
|
||||
Aspect_TypeOfLine Type() const { return myType; }
|
||||
|
||||
//! Modifies the type of line.
|
||||
void SetType (const Aspect_TypeOfLine theType) { myType = theType; }
|
||||
void SetType (const Aspect_TypeOfLine theType)
|
||||
{
|
||||
myType = theType;
|
||||
myLinePattern = DefaultLinePatternForType (theType);
|
||||
}
|
||||
|
||||
//! Return custom stipple line pattern; 0xFFFF by default.
|
||||
uint16_t LinePattern() const { return myLinePattern; }
|
||||
|
||||
//! Modifies the stipple line pattern, and changes line type to Aspect_TOL_USERDEFINED for non-standard pattern.
|
||||
void SetLinePattern (uint16_t thePattern)
|
||||
{
|
||||
myType = DefaultLineTypeForPattern (thePattern);
|
||||
myLinePattern = thePattern;
|
||||
}
|
||||
|
||||
//! Return stipple line pattern for line type.
|
||||
static uint16_t DefaultLinePatternForType (Aspect_TypeOfLine theType)
|
||||
{
|
||||
switch (theType)
|
||||
{
|
||||
case Aspect_TOL_DASH: return 0xFFC0;
|
||||
case Aspect_TOL_DOT: return 0xCCCC;
|
||||
case Aspect_TOL_DOTDASH: return 0xFF18;
|
||||
case Aspect_TOL_EMPTY: return 0x0000;
|
||||
case Aspect_TOL_SOLID: return 0xFFFF;
|
||||
case Aspect_TOL_USERDEFINED: return 0xFF24;
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
//! Return line type for stipple line pattern.
|
||||
static Aspect_TypeOfLine DefaultLineTypeForPattern (uint16_t thePattern)
|
||||
{
|
||||
switch (thePattern)
|
||||
{
|
||||
case 0x0000: return Aspect_TOL_EMPTY;
|
||||
case 0xFFC0: return Aspect_TOL_DASH;
|
||||
case 0xCCCC: return Aspect_TOL_DOT;
|
||||
case 0xFF18: return Aspect_TOL_DOTDASH;
|
||||
case 0xFFFF: return Aspect_TOL_SOLID;
|
||||
case 0xFF24: return Aspect_TOL_USERDEFINED;
|
||||
}
|
||||
return Aspect_TOL_USERDEFINED;
|
||||
}
|
||||
|
||||
//! Return a multiplier for each bit in the line stipple pattern within [1, 256] range; 1 by default.
|
||||
uint16_t LineStippleFactor() const { return myLineFactor; }
|
||||
|
||||
//! Set a multiplier for each bit in the line stipple pattern.
|
||||
void SetLineStippleFactor (uint16_t theFactor)
|
||||
{
|
||||
if (theFactor == 0 || theFactor > 256)
|
||||
{
|
||||
throw Standard_OutOfRange ("Graphic3d_Aspects::SetLineStippleFactor(), bad factor value");
|
||||
}
|
||||
myLineFactor = theFactor;
|
||||
}
|
||||
|
||||
//! Return line width.
|
||||
Standard_ShortReal Width() const { return myWidth; }
|
||||
@@ -97,6 +154,8 @@ public:
|
||||
|
||||
return myProgram == theOther.myProgram
|
||||
&& myType == theOther.myType
|
||||
&& myLineFactor == theOther.myLineFactor
|
||||
&& myLinePattern == theOther.myLinePattern
|
||||
&& myColor == theOther.myColor
|
||||
&& myWidth == theOther.myWidth;
|
||||
}
|
||||
@@ -120,6 +179,8 @@ protected:
|
||||
Quantity_ColorRGBA myColor;
|
||||
Aspect_TypeOfLine myType;
|
||||
Standard_ShortReal myWidth;
|
||||
uint16_t myLineFactor;
|
||||
uint16_t myLinePattern;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -16,7 +16,8 @@
|
||||
#ifndef _Graphic3d_RenderingParams_HeaderFile
|
||||
#define _Graphic3d_RenderingParams_HeaderFile
|
||||
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
#include <Graphic3d_AspectText3d.hxx>
|
||||
#include <Graphic3d_TransformPers.hxx>
|
||||
#include <Graphic3d_RenderTransparentMethod.hxx>
|
||||
#include <Graphic3d_RenderingMode.hxx>
|
||||
#include <Graphic3d_StereoMode.hxx>
|
||||
@@ -44,6 +45,31 @@ public:
|
||||
Anaglyph_UserDefined //!< use externally specified matrices
|
||||
};
|
||||
|
||||
//! Statistics display flags.
|
||||
enum PerfCounters
|
||||
{
|
||||
PerfCounters_NONE = 0x000, //!< no stats
|
||||
PerfCounters_FrameRate = 0x001, //!< Frame Rate
|
||||
PerfCounters_CPU = 0x002, //!< CPU utilization
|
||||
PerfCounters_Layers = 0x004, //!< count layers (groups of structures)
|
||||
PerfCounters_Structures = 0x008, //!< count low-level Structures (normal unhighlighted Presentable Object is usually represented by 1 Structure)
|
||||
//
|
||||
PerfCounters_Groups = 0x010, //!< count primitive Groups (1 Structure holds 1 or more primitive Group)
|
||||
PerfCounters_GroupArrays = 0x020, //!< count Arrays within Primitive Groups (optimal primitive Group holds 1 Array)
|
||||
//
|
||||
PerfCounters_Triangles = 0x040, //!< count Triangles
|
||||
PerfCounters_Points = 0x080, //!< count Points
|
||||
//
|
||||
PerfCounters_EstimMem = 0x100, //!< estimated GPU memory usage
|
||||
//! show basic statistics
|
||||
PerfCounters_Basic = PerfCounters_FrameRate | PerfCounters_CPU | PerfCounters_Layers | PerfCounters_Structures,
|
||||
//! extended (verbose) statistics
|
||||
PerfCounters_Extended = PerfCounters_Basic
|
||||
| PerfCounters_Groups | PerfCounters_GroupArrays
|
||||
| PerfCounters_Triangles | PerfCounters_Points
|
||||
| PerfCounters_EstimMem,
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//! Creates default rendering parameters.
|
||||
@@ -53,6 +79,7 @@ public:
|
||||
OitDepthFactor (0.0f),
|
||||
NbMsaaSamples (0),
|
||||
RenderResolutionScale (1.0f),
|
||||
ToEnableDepthPrepass (Standard_False),
|
||||
// ray tracing parameters
|
||||
IsGlobalIlluminationEnabled (Standard_False),
|
||||
RaytracingDepth (THE_DEFAULT_DEPTH),
|
||||
@@ -77,7 +104,14 @@ public:
|
||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||
ToReverseStereo (Standard_False),
|
||||
|
||||
//
|
||||
StatsPosition (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i (20, 20))),
|
||||
StatsTextAspect (new Graphic3d_AspectText3d()),
|
||||
StatsUpdateInterval (1.0),
|
||||
StatsTextHeight (16),
|
||||
CollectedStats (PerfCounters_Basic),
|
||||
ToShowStats (Standard_False),
|
||||
//
|
||||
Resolution (THE_DEFAULT_RESOLUTION)
|
||||
{
|
||||
const Graphic3d_Vec4 aZero (0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@@ -89,6 +123,13 @@ public:
|
||||
AnaglyphRight.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
|
||||
AnaglyphRight.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
|
||||
AnaglyphRight.SetRow (3, aZero);
|
||||
|
||||
StatsTextAspect->SetColor (Quantity_NOC_WHITE);
|
||||
StatsTextAspect->SetColorSubTitle (Quantity_NOC_BLACK);
|
||||
StatsTextAspect->SetFont (Font_NOF_ASCII_MONO);
|
||||
///StatsTextAspect->SetDisplayType (Aspect_TODT_SHADOW);
|
||||
StatsTextAspect->SetTextZoomable (Standard_False);
|
||||
StatsTextAspect->SetTextFontAspect (Font_FA_Regular);
|
||||
}
|
||||
|
||||
//! Returns resolution ratio.
|
||||
@@ -105,6 +146,7 @@ public:
|
||||
Standard_Integer NbMsaaSamples; //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default
|
||||
Standard_ShortReal RenderResolutionScale; //!< rendering resolution scale factor, 1 by default;
|
||||
//! incompatible with MSAA (e.g. NbMsaaSamples should be set to 0)
|
||||
Standard_Boolean ToEnableDepthPrepass; //!< enables/disables depth pre-pass, False by default
|
||||
|
||||
Standard_Boolean IsGlobalIlluminationEnabled; //!< enables/disables global illumination effects (path tracing)
|
||||
Standard_Integer SamplesPerPixel; //!< number of samples per pixel (SPP)
|
||||
@@ -134,6 +176,20 @@ public:
|
||||
Graphic3d_Mat4 AnaglyphRight; //!< right anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
|
||||
Standard_Boolean ToReverseStereo; //!< flag to reverse stereo pair, FALSE by default
|
||||
|
||||
Handle(Graphic3d_TransformPers) StatsPosition; //!< location of stats, upper-left position by default
|
||||
Handle(Graphic3d_AspectText3d) StatsTextAspect; //!< stats text aspect
|
||||
Standard_ShortReal StatsUpdateInterval; //!< time interval between stats updates in seconds, 1.0 second by default;
|
||||
//! too often updates might impact performance and will smear text within widgets
|
||||
//! (especially framerate, which is better averaging);
|
||||
//! 0.0 interval will force updating on each frame
|
||||
Standard_Integer StatsTextHeight; //!< stats text size; 16 by default
|
||||
PerfCounters CollectedStats; //!< performance counters to collect, PerfCounters_Basic by default;
|
||||
//! too verbose options might impact rendering performance,
|
||||
//! because some counters might lack caching optimization (and will require expensive iteration through all data structures)
|
||||
Standard_Boolean ToShowStats; //!< display performance statistics, FALSE by default;
|
||||
//! note that counters specified within CollectedStats will be updated nevertheless
|
||||
//! of visibility of widget managed by ToShowStats flag (e.g. stats can be retrieved by application for displaying using other methods)
|
||||
|
||||
unsigned int Resolution; //!< Pixels density (PPI), defines scaling factor for parameters like text size
|
||||
//! (when defined in screen-space units rather than in 3D) to be properly displayed
|
||||
//! on device (screen / printer). 72 is default value.
|
||||
|
@@ -49,6 +49,11 @@ public:
|
||||
//! Returns unique ID used to manage resource in graphic driver.
|
||||
const TCollection_AsciiString& GetId() const { return myID; }
|
||||
|
||||
//! Sets unique ID used to manage resource in graphic driver.
|
||||
//! WARNING! Graphic3d_ShaderProgram constructor generates a unique id for proper resource management;
|
||||
//! however if application overrides it, it is responsibility of application to avoid name collisions.
|
||||
void SetId (const TCollection_AsciiString& theId) { myID = theId; }
|
||||
|
||||
//! Returns GLSL header (version code and extensions).
|
||||
const TCollection_AsciiString& Header() const { return myHeader; }
|
||||
|
||||
|
@@ -33,11 +33,14 @@ struct Graphic3d_ZLayerSettings
|
||||
|
||||
//! Default settings.
|
||||
Graphic3d_ZLayerSettings()
|
||||
: myIsImmediate (Standard_False),
|
||||
: myCullingDistance (Precision::Infinite()),
|
||||
myCullingSize (Precision::Infinite()),
|
||||
myIsImmediate (Standard_False),
|
||||
myUseEnvironmentTexture (Standard_True),
|
||||
myToEnableDepthTest (Standard_True),
|
||||
myToEnableDepthWrite(Standard_True),
|
||||
myToClearDepth (Standard_True) {}
|
||||
myToClearDepth (Standard_True),
|
||||
myToRenderInDepthPrepass (Standard_True) {}
|
||||
|
||||
//! Return user-provided name.
|
||||
const TCollection_AsciiString& Name() const { return myName; }
|
||||
@@ -62,6 +65,30 @@ struct Graphic3d_ZLayerSettings
|
||||
}
|
||||
}
|
||||
|
||||
//! Return TRUE, if culling of distant objects (distance culling) should be performed; FALSE by default.
|
||||
//! @sa CullingDistance()
|
||||
Standard_Boolean HasCullingDistance() const { return !Precision::IsInfinite (myCullingDistance) && myCullingDistance > 0.0; }
|
||||
|
||||
//! Return the distance to discard drawing of distant objects (distance from camera Eye point); by default it is Infinite (distance culling is disabled).
|
||||
//! Since camera eye definition has no strong meaning within orthographic projection, option is considered only within perspective projection.
|
||||
//! Note also that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingDistance() const { return myCullingDistance; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingDistance (Standard_Real theDistance) { myCullingDistance = theDistance; }
|
||||
|
||||
//! Return TRUE, if culling of small objects (size culling) should be performed; FALSE by default.
|
||||
//! @sa CullingSize()
|
||||
Standard_Boolean HasCullingSize() const { return !Precision::IsInfinite (myCullingSize) && myCullingSize > 0.0; }
|
||||
|
||||
//! Return the size to discard drawing of small objects; by default it is Infinite (size culling is disabled).
|
||||
//! Current implementation checks the length of projected diagonal of bounding box in pixels for discarding.
|
||||
//! Note that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingSize() const { return myCullingSize; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingSize (Standard_Real theSize) { myCullingSize = theSize; }
|
||||
|
||||
//! Return true if this layer should be drawn after all normal (non-immediate) layers.
|
||||
Standard_Boolean IsImmediate() const { return myIsImmediate; }
|
||||
|
||||
@@ -92,6 +119,12 @@ struct Graphic3d_ZLayerSettings
|
||||
//! Set if depth values should be cleared before drawing the layer.
|
||||
void SetClearDepth (const Standard_Boolean theValue) { myToClearDepth = theValue; }
|
||||
|
||||
//! Return TRUE if layer should be rendered within depth pre-pass; TRUE by default.
|
||||
Standard_Boolean ToRenderInDepthPrepass() const { return myToRenderInDepthPrepass; }
|
||||
|
||||
//! Set if layer should be rendered within depth pre-pass.
|
||||
void SetRenderInDepthPrepass (Standard_Boolean theToRender) { myToRenderInDepthPrepass = theToRender; }
|
||||
|
||||
//! Return glPolygonOffset() arguments.
|
||||
const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; }
|
||||
|
||||
@@ -162,12 +195,15 @@ protected:
|
||||
TCollection_AsciiString myName; //!< user-provided name
|
||||
Handle(Geom_Transformation) myOriginTrsf; //!< transformation to the origin
|
||||
gp_XYZ myOrigin; //!< the origin of all objects within the layer
|
||||
Standard_Real myCullingDistance; //!< distance to discard objects
|
||||
Standard_Real myCullingSize; //!< size to discard objects
|
||||
Graphic3d_PolygonOffset myPolygonOffset; //!< glPolygonOffset() arguments
|
||||
Standard_Boolean myIsImmediate; //!< immediate layer will be drawn after all normal layers
|
||||
Standard_Boolean myUseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
|
||||
Standard_Boolean myToEnableDepthTest; //!< option to enable depth test
|
||||
Standard_Boolean myToEnableDepthWrite; //!< option to enable write depth values
|
||||
Standard_Boolean myToClearDepth; //!< option to clear depth values before drawing the layer
|
||||
Standard_Boolean myToRenderInDepthPrepass;//!< option to render layer within depth pre-pass
|
||||
|
||||
};
|
||||
|
||||
|
@@ -42,7 +42,7 @@ class HLRAlgo_Coincidence
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
Standard_EXPORT HLRAlgo_Coincidence() :
|
||||
HLRAlgo_Coincidence() :
|
||||
myFE(0),
|
||||
myParam(0.),
|
||||
myStBef(TopAbs_IN),
|
||||
|
@@ -382,8 +382,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -470,7 +470,7 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
if (d2 < 0) ad2 = -d2;
|
||||
pp = ad1 / ( ad1 + ad2 );
|
||||
if (TrFlags & HLRAlgo_PolyMask_EMskGrALin2)
|
||||
pdp = (thePoints.PntP1.X() + (thePoints.Pnt2.X() - thePoints.PntP1.X()) * pp - theTriangle.V2.X()) / aD.X();
|
||||
pdp = (thePoints.PntP1.X() + (thePoints.PntP2.X() - thePoints.PntP1.X()) * pp - theTriangle.V2.X()) / aD.X();
|
||||
else
|
||||
pdp = (thePoints.PntP1.Y() + (thePoints.PntP2.Y() - thePoints.PntP1.Y()) * pp - theTriangle.V2.Y()) / aD.Y();
|
||||
Standard_Boolean OutSideP = Standard_False;
|
||||
@@ -524,8 +524,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -666,8 +666,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -326,7 +326,7 @@ HLRAlgo_PolyInternalData::AddNode (
|
||||
Nod3RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_ERROR)
|
||||
cout << "HLRAlgo_PolyInternalData::AddNode" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::AddNode" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return ip3;
|
||||
@@ -415,8 +415,8 @@ HLRAlgo_PolyInternalData::UpdateLinks (const Standard_Integer ip1,
|
||||
myNbPISeg--;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_ERROR) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateLinks : segment error";
|
||||
cout << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateLinks : segment error";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -520,8 +520,8 @@ HLRAlgo_PolyInternalData::UpdateLinks (const Standard_Integer ip1,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyInternalData_ERROR) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateLinks : triangle error ";
|
||||
cout << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateLinks : triangle error ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -640,33 +640,33 @@ void HLRAlgo_PolyInternalData::Dump () const
|
||||
const Handle(HLRAlgo_PolyInternalNode)* pi = &PINod->ChangeValue(i);
|
||||
HLRAlgo_PolyInternalNode::NodeIndices& aNodIndices1 = (*pi)->Indices();
|
||||
HLRAlgo_PolyInternalNode::NodeData& Nod1RValues = (*pi)->Data();
|
||||
cout << "Node " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aNodIndices1.NdSg;
|
||||
cout << setw(20)<< Nod1RValues.Point.X();
|
||||
cout << setw(20)<< Nod1RValues.Point.Y();
|
||||
cout << setw(20)<< Nod1RValues.Point.Z();
|
||||
cout << endl;
|
||||
std::cout << "Node " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aNodIndices1.NdSg;
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.X();
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.Y();
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.Z();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (i = 1; i <= myNbPISeg; i++) {
|
||||
HLRAlgo_PolyInternalSegment* aSegIndices = &PISeg->ChangeValue(i);
|
||||
cout << "Segment " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aSegIndices->LstSg1;
|
||||
cout << setw(6) << aSegIndices->LstSg2;
|
||||
cout << setw(6) << aSegIndices->NxtSg1;
|
||||
cout << setw(6) << aSegIndices->NxtSg2;
|
||||
cout << setw(6) << aSegIndices->Conex1;
|
||||
cout << setw(6) << aSegIndices->Conex2;
|
||||
cout << endl;
|
||||
std::cout << "Segment " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aSegIndices->LstSg1;
|
||||
std::cout << std::setw(6) << aSegIndices->LstSg2;
|
||||
std::cout << std::setw(6) << aSegIndices->NxtSg1;
|
||||
std::cout << std::setw(6) << aSegIndices->NxtSg2;
|
||||
std::cout << std::setw(6) << aSegIndices->Conex1;
|
||||
std::cout << std::setw(6) << aSegIndices->Conex2;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (i = 1; i <= myNbTData; i++) {
|
||||
HLRAlgo_TriangleData& aTriangle = TData->ChangeValue(i);
|
||||
cout << "Triangle " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aTriangle.Node1;
|
||||
cout << setw(6) << aTriangle.Node2;
|
||||
cout << setw(6) << aTriangle.Node3;
|
||||
cout << endl;
|
||||
std::cout << "Triangle " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aTriangle.Node1;
|
||||
std::cout << std::setw(6) << aTriangle.Node2;
|
||||
std::cout << std::setw(6) << aTriangle.Node3;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ void HLRAlgo_PolyInternalData::IncTData(
|
||||
if (myNbTData >= myMxTData) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncTData : " << myMxTData << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncTData : " << myMxTData << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxTData;
|
||||
@@ -720,7 +720,7 @@ void HLRAlgo_PolyInternalData::IncPISeg(
|
||||
if (myNbPISeg >= myMxPISeg) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncPISeg : " << myMxPISeg << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncPISeg : " << myMxPISeg << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxPISeg;
|
||||
@@ -758,7 +758,7 @@ void HLRAlgo_PolyInternalData::IncPINod(
|
||||
if (myNbPINod >= myMxPINod) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncPINod : " << myMxPINod << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncPINod : " << myMxPINod << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxPINod;
|
||||
|
@@ -86,7 +86,6 @@ HLRBRep_ShapeToHLR.cxx
|
||||
HLRBRep_ShapeToHLR.hxx
|
||||
HLRBRep_SLProps.hxx
|
||||
HLRBRep_SLProps_0.cxx
|
||||
HLRBRep_SLPropsATool.cxx
|
||||
HLRBRep_SLPropsATool.hxx
|
||||
HLRBRep_SLPropsATool.lxx
|
||||
HLRBRep_Surface.cxx
|
||||
|
@@ -283,7 +283,7 @@ inline Handle(Geom2d_BezierCurve)
|
||||
HLRBRep_CurveTool::Bezier (const Standard_Address /*C*/)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<" HLRBRep_CurveTool::Bezier : Not Implemented "<<endl;
|
||||
std::cout<<" HLRBRep_CurveTool::Bezier : Not Implemented "<<std::endl;
|
||||
#endif
|
||||
//-- return(((HLRBRep_Curve *)C)->Bezier());
|
||||
return(0);
|
||||
@@ -298,7 +298,7 @@ inline Handle(Geom2d_BSplineCurve)
|
||||
HLRBRep_CurveTool::BSpline (const Standard_Address /*C*/)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<" HLRBRep_CurveTool::BSpline : Not Implemented "<<endl;
|
||||
std::cout<<" HLRBRep_CurveTool::BSpline : Not Implemented "<<std::endl;
|
||||
#endif
|
||||
//-- return(((HLRBRep_Curve *)C)->BSpline());
|
||||
return(0);
|
||||
|
@@ -105,7 +105,7 @@ public:
|
||||
//-- ============================================================
|
||||
void SetDim(const Standard_Integer n) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"\n@#@#@#@#@# SetDim "<<n<<endl;
|
||||
std::cout<<"\n@#@#@#@#@# SetDim "<<n<<std::endl;
|
||||
#endif
|
||||
if(UV)
|
||||
Destroy();
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
~TableauRejection() {
|
||||
//-- cout<<"\n Destructeur TableauRejection"<<endl;
|
||||
//-- std::cout<<"\n Destructeur TableauRejection"<<std::endl;
|
||||
Destroy();
|
||||
}
|
||||
//-- ============================================================
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else
|
||||
cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
|
||||
std::cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
for(i=0;i<N;i++) {
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
UV[i]=NULL;
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else { cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; }
|
||||
else { std::cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl; }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
//-- declaration de la Nv ligne de taille : ancienne taille + SIZEUV
|
||||
//--
|
||||
|
||||
//-- cout<<" \n alloc nbUV["<<i0<<"]="<<nbUV[i0];
|
||||
//-- std::cout<<" \n alloc nbUV["<<i0<<"]="<<nbUV[i0];
|
||||
|
||||
Standard_Real *NvLigneUV = (Standard_Real *) malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Real));
|
||||
Standard_Integer *NvLigneInd = (Standard_Integer *)malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Integer));
|
||||
@@ -280,7 +280,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void ResetTabBit(const Standard_Integer nbedgs) {
|
||||
//-- cout<<"\n ResetTabBit"<<endl;
|
||||
//-- std::cout<<"\n ResetTabBit"<<std::endl;
|
||||
if(TabBit) {
|
||||
for(Standard_Integer i=0;i<nbedgs;i++) {
|
||||
if(TabBit[i]) {
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void InitTabBit(const Standard_Integer nbedgs) {
|
||||
//-- cout<<"\n InitTabBit"<<endl;
|
||||
//-- std::cout<<"\n InitTabBit"<<std::endl;
|
||||
if(TabBit && nTabBit) {
|
||||
ResetTabBit(nTabBit);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void SetNoIntersection(Standard_Integer i0,Standard_Integer i1) {
|
||||
// cout<<" SetNoIntersection : "<<i0<<" "<<i1<<endl;
|
||||
// std::cout<<" SetNoIntersection : "<<i0<<" "<<i1<<std::endl;
|
||||
i0--;
|
||||
i1--;
|
||||
if(i0>i1) {
|
||||
@@ -324,7 +324,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
Standard_Boolean NoIntersection(Standard_Integer i0,Standard_Integer i1) {
|
||||
// cout<<" ??NoIntersection : "<<i0<<" "<<i1<<" ";
|
||||
// std::cout<<" ??NoIntersection : "<<i0<<" "<<i1<<" ";
|
||||
i0--;
|
||||
i1--;
|
||||
if(i0>i1) {
|
||||
@@ -333,10 +333,10 @@ public:
|
||||
Standard_Integer c=i1>>5;
|
||||
Standard_Integer o=i1 & 31;
|
||||
if(TabBit[i0][c] & Mask32[o]) {
|
||||
//-- cout<<" TRUE "<<endl;
|
||||
//-- std::cout<<" TRUE "<<std::endl;
|
||||
return(Standard_True);
|
||||
}
|
||||
//-- cout<<" FALSE "<<endl;
|
||||
//-- std::cout<<" FALSE "<<std::endl;
|
||||
return(Standard_False);
|
||||
}
|
||||
//-- ============================================================
|
||||
@@ -418,7 +418,7 @@ HLRBRep_Data::HLRBRep_Data (const Standard_Integer NV,
|
||||
}
|
||||
|
||||
void HLRBRep_Data::Destroy() {
|
||||
//-- cout<<"\n HLRBRep_Data::~HLRBRep_Data()"<<endl;
|
||||
//-- std::cout<<"\n HLRBRep_Data::~HLRBRep_Data()"<<std::endl;
|
||||
((TableauRejection *)myReject)->Destroy();
|
||||
delete ((TableauRejection *)myReject);
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ void HLRBRep_Data::NextInterference ()
|
||||
GetSingleIntersection(myLE,myFE,su,sv);
|
||||
if(su!=RealLast()) {
|
||||
myIntersector.SimulateOnePoint(myLEData,su,myFEData,sv);
|
||||
//-- cout<<"p";
|
||||
//-- std::cout<<"p";
|
||||
}
|
||||
else {
|
||||
myIntersector.Perform
|
||||
@@ -1224,13 +1224,13 @@ void HLRBRep_Data::NextInterference ()
|
||||
else {
|
||||
myNbPoints = myNbSegments = 0;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::NextInterference : ";
|
||||
std::cout << "HLRBRep_Data::NextInterference : ";
|
||||
if (myLE == myFE)
|
||||
cout << "Edge " << myLE
|
||||
<< " : Intersection not done" << endl;
|
||||
std::cout << "Edge " << myLE
|
||||
<< " : Intersection not done" << std::endl;
|
||||
else
|
||||
cout << "Edges " << myLE << " , " << myFE
|
||||
<< " : Intersection not done" << endl;
|
||||
std::cout << "Edges " << myLE << " , " << myFE
|
||||
<< " : Intersection not done" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1246,7 +1246,7 @@ void HLRBRep_Data::NextInterference ()
|
||||
}
|
||||
}
|
||||
else {
|
||||
//-- cout<<"+";
|
||||
//-- std::cout<<"+";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1391,7 +1391,7 @@ void HLRBRep_Data::EdgeState (const Standard_Real p1,
|
||||
stbef = TopAbs_OUT;
|
||||
staft = TopAbs_OUT;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::EdgeState : undefined" << endl;
|
||||
std::cout << "HLRBRep_Data::EdgeState : undefined" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1399,7 +1399,7 @@ void HLRBRep_Data::EdgeState (const Standard_Real p1,
|
||||
stbef = TopAbs_OUT;
|
||||
staft = TopAbs_OUT;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::EdgeState : undefined" << endl;
|
||||
std::cout << "HLRBRep_Data::EdgeState : undefined" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1464,8 +1464,8 @@ HLRBRep_Data::HidingStartLevel (const Standard_Integer E,
|
||||
Loop = Standard_False;
|
||||
else {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::HidingStartLevel : ";
|
||||
cout << "Bad Parameter." << endl;
|
||||
std::cout << "HLRBRep_Data::HidingStartLevel : ";
|
||||
std::cout << "Bad Parameter." << std::endl;
|
||||
#endif
|
||||
}
|
||||
It.Next();
|
||||
@@ -1548,9 +1548,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
gp_Vec Nm = mySLProps.Normal();
|
||||
if (curv == 0) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "CurvatureValue == 0." << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "CurvatureValue == 0." << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (curv > 0)
|
||||
@@ -1561,9 +1561,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
Nm.Cross(Tg);
|
||||
if (Tg.Magnitude() < gp::Resolution()) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "Tg.Magnitude() == 0." << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "Tg.Magnitude() == 0." << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (myProj.Perspective())
|
||||
@@ -1583,9 +1583,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
}
|
||||
else {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "UVPoint not found, OutLine not Oriented" << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "UVPoint not found, OutLine not Oriented" << std::endl;
|
||||
#endif
|
||||
}
|
||||
ed1.Used(Standard_True);
|
||||
@@ -1644,9 +1644,9 @@ void HLRBRep_Data::OrientOthEdge (const Standard_Integer I,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << "HLRBRep_Data::OrientOthEdge " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "UVPoint not found, Edge not Oriented" << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOthEdge " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "UVPoint not found, Edge not Oriented" << std::endl;
|
||||
}
|
||||
#else
|
||||
(void)I; // avoid compiler warning
|
||||
@@ -1863,7 +1863,7 @@ HLRBRep_Data::Classify (const Standard_Integer E,
|
||||
q2 = (q& 0x0000FFFF);
|
||||
printf("\nmot: %3d q1 = %+10d q2=%+10d Mask : %d",qwe+8,(q1>32768)? (32768-q1) : q1,(q2>32768)? (32768-q2) : q2,q&0x80008000);
|
||||
}
|
||||
cout<<endl;
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
@@ -235,7 +235,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state staft" << endl;
|
||||
std::cout << "UNKNOWN state staft" << std::endl;
|
||||
#endif
|
||||
case TopAbs_ON :
|
||||
It.Next(); break;
|
||||
@@ -249,7 +249,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state stbef" << endl;
|
||||
std::cout << "UNKNOWN state stbef" << std::endl;
|
||||
#endif
|
||||
case TopAbs_ON :
|
||||
It.Next(); break;
|
||||
@@ -279,7 +279,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
It.Next(); break;
|
||||
} break;
|
||||
@@ -299,7 +299,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
Int.Transition(TopAbs_REVERSED); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -317,13 +317,13 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
It.Next(); break;
|
||||
} break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state stbef" << endl;
|
||||
std::cout << "UNKNOWN state stbef" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -370,14 +370,14 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
{
|
||||
ToRemove.Append(Int.Intersection().Parameter());
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"Two adjacent interferences with transition FORWARD"<<endl;
|
||||
std::cout<<"Two adjacent interferences with transition FORWARD"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
else if (aTrans == TopAbs_REVERSED)
|
||||
{
|
||||
ToRemove.Append(PrevParam);
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"Two adjacent interferences with transition REVERSED"<<endl;
|
||||
std::cout<<"Two adjacent interferences with transition REVERSED"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -698,9 +698,9 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
|
||||
catch(Standard_Failure const& anException) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "An exception was catched when hiding edge " << E;
|
||||
cout << " by the face " << FI << endl;
|
||||
cout << anException << endl;
|
||||
std::cout << "An exception was catched when hiding edge " << E;
|
||||
std::cout << " by the face " << FI << std::endl;
|
||||
std::cout << anException << std::endl;
|
||||
#endif
|
||||
(void)anException;
|
||||
}
|
||||
|
@@ -114,9 +114,9 @@ void HLRBRep_InternalAlgo::Update ()
|
||||
catch(Standard_Failure const& anException) {
|
||||
if (myDebug)
|
||||
{
|
||||
cout << "An exception was catched when preparing the Shape " << i;
|
||||
cout << " and computing its OutLines " << endl;
|
||||
cout << anException << endl;
|
||||
std::cout << "An exception was catched when preparing the Shape " << i;
|
||||
std::cout << " and computing its OutLines " << std::endl;
|
||||
std::cout << anException << std::endl;
|
||||
}
|
||||
DS[i-1] = new HLRBRep_Data(0,0,0);
|
||||
dv = 0;
|
||||
@@ -165,7 +165,7 @@ void HLRBRep_InternalAlgo::Update ()
|
||||
SB.Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
for (Standard_Integer e = e1; e <= e2; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
HLRAlgo::DecodeMinMax(ed.MinMax(), TheMin, TheMax);
|
||||
if (FirstTime) {
|
||||
FirstTime = Standard_False;
|
||||
@@ -307,7 +307,7 @@ void HLRBRep_InternalAlgo::InitEdgeStatus ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().ShowAll();
|
||||
}
|
||||
// for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
@@ -368,7 +368,7 @@ void HLRBRep_InternalAlgo::Select ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(Standard_True);
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ void HLRBRep_InternalAlgo::PartialHide ()
|
||||
Standard_Integer i,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Partial hiding" << endl << endl;
|
||||
std::cout << " Partial hiding" << std::endl << std::endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
@@ -576,7 +576,7 @@ void HLRBRep_InternalAlgo::Hide ()
|
||||
Standard_Integer i,j,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Total hiding" << endl;
|
||||
std::cout << " Total hiding" << std::endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
@@ -602,7 +602,7 @@ void HLRBRep_InternalAlgo::Hide (const Standard_Integer I)
|
||||
"HLRBRep_InternalAlgo::Hide : unknown Shape");
|
||||
|
||||
if (myDebug)
|
||||
cout << " hiding the shape " << I << " by itself" << endl;
|
||||
std::cout << " hiding the shape " << I << " by itself" << std::endl;
|
||||
|
||||
Select(I);
|
||||
InitEdgeStatus();
|
||||
@@ -643,8 +643,8 @@ void HLRBRep_InternalAlgo::Hide (const Standard_Integer I,
|
||||
((MinMaxShBJ->Max[6] - MinMaxShBI->Min[6]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[7] - MinMaxShBI->Min[7]) & 0x80008000) == 0) {
|
||||
if (myDebug) {
|
||||
cout << " hiding the shape " << I;
|
||||
cout << " by the shape : " << J << endl;
|
||||
std::cout << " hiding the shape " << I;
|
||||
std::cout << " by the shape : " << J << std::endl;
|
||||
}
|
||||
SelectEdge(I);
|
||||
SelectFace(J);
|
||||
@@ -717,17 +717,17 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
|
||||
if (myDebug)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "Vertices : " << setw(5) << myDS->NbVertices() << endl;
|
||||
cout << "Edges : " << setw(5) << myDS->NbEdges() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelEdges << " , ";
|
||||
cout << "Visibles : " << setw(5) << nbVisEdges << endl;
|
||||
cout << "Faces : " << setw(5) << myDS->NbFaces() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelFaces << " , ";
|
||||
cout << "Simple : " << setw(5) << nbFSimp << endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Vertices : " << std::setw(5) << myDS->NbVertices() << std::endl;
|
||||
std::cout << "Edges : " << std::setw(5) << myDS->NbEdges() << " , ";
|
||||
std::cout << "Selected : " << std::setw(5) << nbSelEdges << " , ";
|
||||
std::cout << "Visibles : " << std::setw(5) << nbVisEdges << std::endl;
|
||||
std::cout << "Faces : " << std::setw(5) << myDS->NbFaces() << " , ";
|
||||
std::cout << "Selected : " << std::setw(5) << nbSelFaces << " , ";
|
||||
std::cout << "Simple : " << std::setw(5) << nbFSimp << std::endl;
|
||||
if (SideFace)
|
||||
cout << "Side : " << setw(5) << nbFSide << " , ";
|
||||
cout << "Cachantes : " << setw(5) << nbCache << endl << endl;
|
||||
std::cout << "Side : " << std::setw(5) << nbFSide << " , ";
|
||||
std::cout << "Cachantes : " << std::setw(5) << nbCache << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,13 +748,13 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
if(++QWE>QWEQWE) {
|
||||
QWE=0;
|
||||
if (myDebug)
|
||||
cout<<"*";
|
||||
std::cout<<"*";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (myDebug && HLRBRep_InternalAlgo_TRACE) {
|
||||
j++;
|
||||
cout << " OwnHiding " << j << " of face : " << f << endl;
|
||||
std::cout << " OwnHiding " << j << " of face : " << f << std::endl;
|
||||
}
|
||||
}
|
||||
Cache.OwnHiding(f);
|
||||
@@ -867,7 +867,7 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
if(HLRBRep_InternalAlgo_TRACE10 && HLRBRep_InternalAlgo_TRACE==Standard_False) {
|
||||
if(++QWE>QWEQWE) {
|
||||
if (myDebug)
|
||||
cout<<".";
|
||||
std::cout<<".";
|
||||
QWE=0;
|
||||
}
|
||||
}
|
||||
@@ -892,22 +892,22 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
nbFSimp++;
|
||||
}
|
||||
|
||||
cout << "\n";
|
||||
cout << "Simple Faces : ";
|
||||
cout << nbFSimp << "\n";
|
||||
cout << "Intersections calculees : ";
|
||||
cout << nbCal2Intersection << "\n";
|
||||
cout << "Intersections Ok : ";
|
||||
cout << nbOkIntersection << "\n";
|
||||
cout << "Points : ";
|
||||
cout << nbPtIntersection << "\n";
|
||||
cout << "Segments : ";
|
||||
cout << nbSegIntersection << "\n";
|
||||
cout << "Classification : ";
|
||||
cout << nbClassification << "\n";
|
||||
cout << "Intersections curve-surface : ";
|
||||
cout << nbCal3Intersection << "\n";
|
||||
cout << endl << endl;
|
||||
std::cout << "\n";
|
||||
std::cout << "Simple Faces : ";
|
||||
std::cout << nbFSimp << "\n";
|
||||
std::cout << "Intersections calculees : ";
|
||||
std::cout << nbCal2Intersection << "\n";
|
||||
std::cout << "Intersections Ok : ";
|
||||
std::cout << nbOkIntersection << "\n";
|
||||
std::cout << "Points : ";
|
||||
std::cout << nbPtIntersection << "\n";
|
||||
std::cout << "Segments : ";
|
||||
std::cout << nbSegIntersection << "\n";
|
||||
std::cout << "Classification : ";
|
||||
std::cout << nbClassification << "\n";
|
||||
std::cout << "Intersections curve-surface : ";
|
||||
std::cout << nbCal3Intersection << "\n";
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -159,7 +159,7 @@ public:
|
||||
|
||||
static Standard_Integer NbSamples (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1);
|
||||
|
||||
Standard_EXPORT static void SamplePars (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1, const Standard_Real Defl, const Standard_Integer NbMin, Handle(TColStd_HArray1OfReal)& Pars);
|
||||
static void SamplePars (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1, const Standard_Real Defl, const Standard_Integer NbMin, Handle(TColStd_HArray1OfReal)& Pars);
|
||||
|
||||
|
||||
|
||||
|
@@ -438,13 +438,20 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
PD (f) = new HLRAlgo_PolyData();
|
||||
psd->PolyData().ChangeValue(iFace) = PD(f);
|
||||
PID(f) = new HLRAlgo_PolyInternalData(nbN,nbT);
|
||||
Handle(HLRAlgo_PolyInternalData)& pid =
|
||||
*(Handle(HLRAlgo_PolyInternalData)*)&(PID(f));
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
|
||||
if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
|
||||
S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
|
||||
GeomAdaptor_Surface AS(S);
|
||||
pid->Planar(AS.GetType() == GeomAbs_Plane);
|
||||
Handle(HLRAlgo_PolyInternalData)& pid = *(Handle(HLRAlgo_PolyInternalData)*)&(PID(f));
|
||||
if (Handle(Geom_Surface) S = BRep_Tool::Surface(F))
|
||||
{
|
||||
if (Handle(Geom_RectangularTrimmedSurface) aRectTrimSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(S))
|
||||
{
|
||||
S = aRectTrimSurf->BasisSurface();
|
||||
}
|
||||
GeomAdaptor_Surface AS(S);
|
||||
pid->Planar(AS.GetType() == GeomAbs_Plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
pid->Planar (false);
|
||||
}
|
||||
HLRAlgo_Array1OfTData* TData = &pid->TData();
|
||||
HLRAlgo_Array1OfPISeg* PISeg = &pid->PISeg();
|
||||
HLRAlgo_Array1OfPINod* PINod = &pid->PINod();
|
||||
@@ -501,8 +508,8 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << " HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
cout << f << " non triangulated" << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
std::cout << f << " non triangulated" << std::endl;
|
||||
}
|
||||
#endif
|
||||
NT = &(((HLRAlgo_Array1OfTData*)TData)->ChangeValue(1));
|
||||
@@ -527,8 +534,8 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
cout << f << " deja stockee" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
std::cout << f << " deja stockee" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -656,8 +663,8 @@ Normal (const Standard_Integer iNode,
|
||||
Nod1RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::Normal : AverageNormal error";
|
||||
cout << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::Normal : AverageNormal error";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -733,8 +740,8 @@ HLRBRep_PolyAlgo::AverageNormal(const Standard_Integer iNode,
|
||||
OK = Standard_False;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData:: inverted normals on ";
|
||||
cout << "node " << iNode << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData:: inverted normals on ";
|
||||
std::cout << "node " << iNode << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -875,8 +882,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -906,10 +913,10 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
if (Nod11RValues->Normal.X()*Nod12RValues->Normal.X() +
|
||||
Nod11RValues->Normal.Y()*Nod12RValues->Normal.Y() +
|
||||
Nod11RValues->Normal.Z()*Nod12RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Too big angle between " << i1p1 << setw(6);
|
||||
cout << " and " << i1p2 << setw(6);
|
||||
cout << " in face " << i1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Too big angle between " << i1p1 << std::setw(6);
|
||||
std::cout << " and " << i1p2 << std::setw(6);
|
||||
std::cout << " in face " << i1 << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -927,8 +934,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -945,8 +952,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " connex 1 sans PolygonOnTriangulation" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " connex 1 sans PolygonOnTriangulation" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1041,8 +1048,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -1085,18 +1092,18 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
if (Nod11RValues->Normal.X()*Nod12RValues->Normal.X() +
|
||||
Nod11RValues->Normal.Y()*Nod12RValues->Normal.Y() +
|
||||
Nod11RValues->Normal.Z()*Nod12RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "To big angle between " << i1p1 << setw(6);
|
||||
cout << " and " << i1p2 << setw(6);
|
||||
cout << " in face " << i1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "To big angle between " << i1p1 << std::setw(6);
|
||||
std::cout << " and " << i1p2 << std::setw(6);
|
||||
std::cout << " in face " << i1 << std::endl;
|
||||
}
|
||||
if (Nod21RValues->Normal.X()*Nod22RValues->Normal.X() +
|
||||
Nod21RValues->Normal.Y()*Nod22RValues->Normal.Y() +
|
||||
Nod21RValues->Normal.Z()*Nod22RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "To big angle between " << i2p1 << setw(6);
|
||||
cout << " and " << i2p2 << setw(6);
|
||||
cout<< " in face " << i2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "To big angle between " << i2p1 << std::setw(6);
|
||||
std::cout << " and " << i2p2 << std::setw(6);
|
||||
std::cout<< " in face " << i2 << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1114,8 +1121,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -1136,8 +1143,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " connect 2 without PolygonOnTriangulation" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " connect 2 without PolygonOnTriangulation" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1198,8 +1205,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " Isolated, without Polygone 3D" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " Isolated, without Polygone 3D" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1489,8 +1496,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1521,8 +1528,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1644,8 +1651,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1656,8 +1663,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod21Indices.Edg2 == e) Nod21RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod21RValues.Scal = 0;
|
||||
@@ -1693,8 +1700,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1705,8 +1712,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod22Indices.Edg2 == e) Nod22RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod22RValues.Scal = 0;
|
||||
@@ -1853,8 +1860,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1865,8 +1872,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod21Indices.Edg2 == e) Nod21RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod21RValues.Scal = 0;
|
||||
@@ -1902,8 +1909,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U4;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1914,8 +1921,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod22Indices.Edg2 == e) Nod22RValues.PCu2 = U4;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod22RValues.Scal = 0;
|
||||
@@ -2078,9 +2085,9 @@ HLRBRep_PolyAlgo::InsertOnOutLine (TColStd_Array1OfTransient& PID)
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << endl;
|
||||
cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << endl;
|
||||
cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << endl;
|
||||
std::cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2162,9 +2169,9 @@ HLRBRep_PolyAlgo::InsertOnOutLine (TColStd_Array1OfTransient& PID)
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << endl;
|
||||
cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << endl;
|
||||
cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << endl;
|
||||
std::cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2241,7 +2248,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
(tdata->Flags & HLRAlgo_PolyMask_FMskFrBack)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << " face : " << f << " , triangle " << i << endl;
|
||||
std::cout << " face : " << f << " , triangle " << i << std::endl;
|
||||
#endif
|
||||
Modif = Standard_True;
|
||||
const Handle(HLRAlgo_PolyInternalNode)* pi1p1 =
|
||||
@@ -2310,8 +2317,8 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node1 << " modifies : DX,DY ";
|
||||
cout << X1 << " , " << Y1 << endl;
|
||||
std::cout << tdata->Node1 << " modifies : DX,DY ";
|
||||
std::cout << X1 << " , " << Y1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2323,8 +2330,8 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node2 << " modifies : DX,DY ";
|
||||
cout << X2 << " , " << Y2 << endl;
|
||||
std::cout << tdata->Node2 << " modifies : DX,DY ";
|
||||
std::cout << X2 << " , " << Y2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2336,14 +2343,14 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node3 << " modifies : DX,DY ";
|
||||
cout << X3 << " , " << Y3 << endl;
|
||||
std::cout << tdata->Node3 << " modifies : DX,DY ";
|
||||
std::cout << X3 << " , " << Y3 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoTrace)
|
||||
cout << "modification error" << endl;
|
||||
std::cout << "modification error" << std::endl;
|
||||
#endif
|
||||
}
|
||||
tdata++;
|
||||
@@ -2383,7 +2390,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face1Pt1 << " modifies 11" << endl;
|
||||
std::cout << theIndices.Face1Pt1 << " modifies 11" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod1->ChangeValue(theIndices.Face1Pt1)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2402,7 +2409,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face1Pt2 << " modifies 12" << endl;
|
||||
std::cout << theIndices.Face1Pt2 << " modifies 12" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod1->ChangeValue(theIndices.Face1Pt2)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2426,7 +2433,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face2Pt1 << " modifies 21" << endl;
|
||||
std::cout << theIndices.Face2Pt1 << " modifies 21" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod2->ChangeValue(theIndices.Face2Pt1)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2445,7 +2452,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face2Pt2 << " modifies 22" << endl;
|
||||
std::cout << theIndices.Face2Pt2 << " modifies 22" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod2->ChangeValue(theIndices.Face2Pt2)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2563,8 +2570,8 @@ void HLRBRep_PolyAlgo::ChangeNode (const Standard_Integer ip1,
|
||||
Nod1RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip1;
|
||||
cout << " and " << ip2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip1;
|
||||
std::cout << " and " << ip2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2583,8 +2590,8 @@ void HLRBRep_PolyAlgo::ChangeNode (const Standard_Integer ip1,
|
||||
Nod2RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip2;
|
||||
cout << " and " << ip1 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip2;
|
||||
std::cout << " and " << ip1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2684,8 +2691,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskOnOutL;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : OnOutL";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : OnOutL";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2717,8 +2724,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD12Norm <= 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2731,8 +2738,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD23Norm < 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2745,8 +2752,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD31Norm < 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2761,8 +2768,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aDNorm < 1.e-5) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2838,8 +2845,8 @@ HLRBRep_PolyAlgo::Triangles(const Standard_Integer ip1,
|
||||
iTri2 = 0;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::Triangles : error";
|
||||
cout << " between " << ip1 << " and " << ip2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::Triangles : error";
|
||||
std::cout << " between " << ip1 << " and " << ip2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
return Standard_False;
|
||||
@@ -2975,8 +2982,8 @@ HLRBRep_PolyAlgo::UpdateOutLines (HLRAlgo_ListOfBPoint& List,
|
||||
aTriangle.Flags |= HLRAlgo_PolyMask_EMskOutLin3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
cout << " : segment not found" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
std::cout << " : segment not found" << std::endl;
|
||||
}
|
||||
#endif
|
||||
tn1 = aTriangle2.Node1;
|
||||
@@ -2995,8 +3002,8 @@ HLRBRep_PolyAlgo::UpdateOutLines (HLRAlgo_ListOfBPoint& List,
|
||||
aTriangle2.Flags |= HLRAlgo_PolyMask_EMskOutLin3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
cout << " : segment not found" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
std::cout << " : segment not found" << std::endl;
|
||||
}
|
||||
#endif
|
||||
HLRAlgo_PolyInternalNode::NodeData& Nod1RValues =
|
||||
@@ -3081,9 +3088,9 @@ UpdateEdgesBiPoints (HLRAlgo_ListOfBPoint& List,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::UpdateEdgesBiPoints : error ";
|
||||
cout << " between " << aIndices.FaceConex1 << setw(6);
|
||||
cout << " and " << aIndices.FaceConex2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::UpdateEdgesBiPoints : error ";
|
||||
std::cout << " between " << aIndices.FaceConex1 << std::setw(6);
|
||||
std::cout << " and " << aIndices.FaceConex2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3133,9 +3140,9 @@ HLRBRep_PolyAlgo::UpdatePolyData (TColStd_Array1OfTransient& PD,
|
||||
if (!(OT->Flags & HLRAlgo_PolyMask_FMskSide)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if ((OT->Flags & HLRAlgo_PolyMask_FMskFrBack) && DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::ReverseBackTriangle :";
|
||||
cout << " face " << f << setw(6);
|
||||
cout << " triangle " << i << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ReverseBackTriangle :";
|
||||
std::cout << " face " << f << std::setw(6);
|
||||
std::cout << " triangle " << i << std::endl;
|
||||
}
|
||||
#endif
|
||||
if (OT->Flags & HLRAlgo_PolyMask_FMskOrBack) {
|
||||
|
@@ -49,7 +49,7 @@ public:
|
||||
//! <V> on the Surface <A>.
|
||||
static void D2 (const Standard_Address A, 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& DUV);
|
||||
|
||||
Standard_EXPORT static gp_Vec DN (const Standard_Address A, const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv);
|
||||
static gp_Vec DN (const Standard_Address A, const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv);
|
||||
|
||||
//! returns the order of continuity of the Surface
|
||||
//! <A>. returns 1 : first derivative only is
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
@@ -228,7 +228,7 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
|
||||
|
||||
if(ipL-ipF < 1) {
|
||||
InsuffisantNumberOfPoints=Standard_True;
|
||||
//cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
|
||||
//std::cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<std::endl;
|
||||
}
|
||||
/*
|
||||
else if(ipL-ipF < 6) {
|
||||
@@ -390,7 +390,7 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
|
||||
TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
|
||||
TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
|
||||
|
||||
//-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<endl;
|
||||
//-- std::cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<std::endl;
|
||||
|
||||
Approx.SetParameters(TOL3d, TOL2d, dmin, dmax, niter, 30, tg);
|
||||
Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
|
||||
|
@@ -197,23 +197,23 @@ void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
|
||||
Hatcher.ComputeDomains (IndH);
|
||||
if (!Hatcher.IsDone (IndH)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
|
||||
cout << "U iso of parameter: " << UPrm;
|
||||
std::cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << std::endl;
|
||||
std::cout << "U iso of parameter: " << UPrm;
|
||||
switch (Hatcher.Status (IndH)) {
|
||||
case HatchGen_NoProblem :
|
||||
cout << " No Problem" << endl;
|
||||
std::cout << " No Problem" << std::endl;
|
||||
break;
|
||||
case HatchGen_TrimFailure :
|
||||
cout << " Trim Failure" << endl;
|
||||
std::cout << " Trim Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_TransitionFailure :
|
||||
cout << " Transition Failure" << endl;
|
||||
std::cout << " Transition Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncoherentParity :
|
||||
cout << " Incoherent Parity" << endl;
|
||||
std::cout << " Incoherent Parity" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncompatibleStates :
|
||||
cout << " Incompatible States" << endl;
|
||||
std::cout << " Incompatible States" << std::endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -291,23 +291,23 @@ void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
|
||||
Hatcher.ComputeDomains (IndH);
|
||||
if (!Hatcher.IsDone (IndH)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
|
||||
cout << "V iso of parameter: " << VPrm;
|
||||
std::cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << std::endl;
|
||||
std::cout << "V iso of parameter: " << VPrm;
|
||||
switch (Hatcher.Status (IndH)) {
|
||||
case HatchGen_NoProblem :
|
||||
cout << " No Problem" << endl;
|
||||
std::cout << " No Problem" << std::endl;
|
||||
break;
|
||||
case HatchGen_TrimFailure :
|
||||
cout << " Trim Failure" << endl;
|
||||
std::cout << " Trim Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_TransitionFailure :
|
||||
cout << " Transition Failure" << endl;
|
||||
std::cout << " Transition Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncoherentParity :
|
||||
cout << " Incoherent Parity" << endl;
|
||||
std::cout << " Incoherent Parity" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncompatibleStates :
|
||||
cout << " Incompatible States" << endl;
|
||||
std::cout << " Incompatible States" << std::endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@@ -296,7 +296,7 @@ IGESData_IGESReaderTool::IGESData_IGESReaderTool
|
||||
Msg34.Arg(thecnum);
|
||||
Msg34.Arg(thectyp.Type());
|
||||
ach->SendWarning(Msg34);
|
||||
ent->InitDirFieldEntity(13,fieldent);
|
||||
ent->InitDirFieldEntity(13, Color);
|
||||
}
|
||||
else ent->InitColor(Color);
|
||||
}
|
||||
|
@@ -930,21 +930,19 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
// 3. ts1 == ts2 == 0 <Param-Param>
|
||||
|
||||
// Geom - Geom
|
||||
const Standard_Boolean RestrictLine = Standard_True;
|
||||
if(ts1 == ts2 && ts1 == 1)
|
||||
{
|
||||
IntSurf_ListOfPntOn2S ListOfPnts;
|
||||
ListOfPnts.Clear();
|
||||
if(isGeomInt)
|
||||
{
|
||||
GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine,
|
||||
typs1, typs2, theIsReqToKeepRLine);
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
|
||||
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,7 +959,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
ListOfPnts.Clear();
|
||||
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
|
||||
if(!theIsReqToPostWLProc)
|
||||
@@ -978,7 +976,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
@@ -999,7 +997,6 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const Standard_Boolean isGeomInt,
|
||||
const Standard_Boolean theIsReqToKeepRLine,
|
||||
const Standard_Boolean theIsReqToPostWLProc)
|
||||
@@ -1183,7 +1180,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
if(!isGeomInt)
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
else if(ts1 != ts2)
|
||||
{
|
||||
@@ -1192,12 +1189,12 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
else if (ts1 == 0)
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
else if(ts1 == 1)
|
||||
{
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
|
||||
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
|
||||
}
|
||||
|
||||
if(!theIsReqToPostWLProc)
|
||||
@@ -1214,7 +1211,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
@@ -1235,7 +1232,6 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const GeomAbs_SurfaceType typs1,
|
||||
const GeomAbs_SurfaceType typs2)
|
||||
{
|
||||
@@ -1245,10 +1241,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
|
||||
Standard_Boolean ClearFlag = Standard_True;
|
||||
if(!ListOfPnts.IsEmpty())
|
||||
{
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts);
|
||||
ClearFlag = Standard_False;
|
||||
}
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!!
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);
|
||||
}
|
||||
else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
|
||||
{
|
||||
@@ -1345,7 +1341,6 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const GeomAbs_SurfaceType theTyps1,
|
||||
const GeomAbs_SurfaceType theTyps2,
|
||||
const Standard_Boolean theIsReqToKeepRLine)
|
||||
@@ -1357,7 +1352,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
{
|
||||
done = Standard_False;
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
|
||||
TolArc, TolTang, ListOfPnts, theTyps1, theTyps2);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1604,7 +1599,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
|
@@ -70,16 +70,16 @@ public:
|
||||
//!
|
||||
//! UVMaxStep is a parameter used in the walking
|
||||
//! algorithms to compute the distance between to
|
||||
//! points in their respective parametrtic spaces.
|
||||
//! points in their respective parametric spaces.
|
||||
Standard_EXPORT void SetTolerances (const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Real UVMaxStep, const Standard_Real Fleche);
|
||||
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
//! Flag theIsReqToPostWLProc has been enterred only for
|
||||
//! Flag theIsReqToPostWLProc has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
|
||||
@@ -88,18 +88,18 @@ public:
|
||||
|
||||
//! If isGeomInt == Standard_False, then method
|
||||
//! Param-Param intersection will be used.
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
//! Flag theIsReqToPostWLProc has been enterred only for
|
||||
//! Flag theIsReqToPostWLProc has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
|
||||
//! obtained after intersection algorithm directly (wothout any post-processing).
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
|
||||
//! obtained after intersection algorithm directly (without any post-processing).
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
|
||||
|
||||
//! Perform with start point
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2, const Standard_Real TolArc, const Standard_Real TolTang);
|
||||
@@ -107,14 +107,14 @@ public:
|
||||
//! Uses for finding self-intersected surfaces.
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolArc, const Standard_Real TolTang);
|
||||
|
||||
//! Returns True if the calculus was succesfull.
|
||||
//! Returns True if the calculus was successful.
|
||||
Standard_Boolean IsDone() const;
|
||||
|
||||
//! Returns true if the is no intersection.
|
||||
Standard_Boolean IsEmpty() const;
|
||||
|
||||
//! Returns True if the two patches are considered as
|
||||
//! entierly tangent, i-e every restriction arc of one
|
||||
//! entirely tangent, i-e every restriction arc of one
|
||||
//! patch is inside the geometric base of the other patch.
|
||||
Standard_Boolean TangentFaces() const;
|
||||
|
||||
@@ -157,15 +157,15 @@ protected:
|
||||
private:
|
||||
|
||||
|
||||
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine = Standard_False);
|
||||
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine);
|
||||
|
||||
Standard_EXPORT void GeomParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Boolean isNotAnalitical, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user