1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Compare commits

..

45 Commits

Author SHA1 Message Date
oan
cb2e41f927 Exact intersection of discrete segments 2019-11-04 22:04:04 +03:00
vro
6466cc9eb1 0031117: Visualization, AIS_ViewCube - additional properties for visualization of trihedron of a View Cube
AIS_ViewCube has been extended by additional properties (previously hard-coded):
- radius of axes of the trihedron
- radius of cones of the axes of the trihedron
- radius of a sphere (central point) of the trihedron

ViewerTest command vviewcube has been extended to support new parameters:
-axesradius, -axesconeradius, -axessphereradius.
2019-11-01 18:29:12 +03:00
osa
f7fc0c03be 0029367: Visualization - simplify interface of V3d_View and V3d_Viewer
The interface of V3d_View and V3d_Viewer has been simplified.
For the fields myDefinedViews, myActiveViews, myDefinedLights, myActiveLights were added appropriate methods returning the internal raw data.
Make the next methods deprecated:
IfMoreLights(), InitActiveLights(), MoreActiveLights(), NextActiveLights(), ActiveLight() and
InitActiveViews(), MoreActiveViews(), NextActiveViews(), ActiveView(), InitDefinedViews(), MoreDefinedViews(), NextDefinedViews(), DefinedView(),
InitActiveLights(), MoreActiveLights(), NextActiveLights(), ActiveLight(), InitDefinedLights(), MoreDefinedLights(), NextDefinedLights(), DefinedLight().

Remove deprecated methods added in scope of tasks 0029290 and 0028987 (Target Version 7.3.0):
SelectMgr_SelectableObject: Init(), More(), Next(), CurrentSelection().
SelectMgr_Selection: Init(), More(), Next(), Sensitive().
V3d_AmbientLight: one constructor.
V3d_DirectionalLight: two constructors.
V3d_PositionalLight: one constructor.
V3d_SpotLight: two constructors.
2019-11-01 18:27:06 +03:00
iko
67312b7991 0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
Metallic-Roughness shading model Graphic3d_TOSM_PBR has been implemented.
New materials descriptors Graphic3d_PBRMaterial have been added to Graphic3d_MaterialAspect.
PBR shading model requires OpenGL 3.0+ or OpenGL ES 3.0+ hardware.
Environment cubemap is expected to be provided for realistic look of metallic materials.

occLight_IsHeadlight() now returns bool instead of int.
Avoid using lowp for enumerations to workaround occLight_IsHeadlight()
ignorance on Adreno 308 caused by some GLSL optimizator bugs.

OpenGl_Texture::EstimatedDataSize() - fixed estimation for Cubemap textures.
OpenGl_Sampler::applySamplerParams() - fixed uninitialized GL_TEXTURE_WRAP_R in case of GL_TEXTURE_CUBE_MAP target.
2019-11-01 18:25:28 +03:00
tiv
f4a7308f61 0030609: Coding - eliminate warnings issued by gcc 8.1.0
Warnings issued by gcc 8.1.0 are eliminated.

New Standard_WarningDisableFunctionCast.hxx header file is introduced to disable GCC warning "-Wcast-function-type" in those files *.cxx where it is issued. This warning is issued when the conversion from the pointer to one function type to the pointer to another function type takes places, it was added in gcc 8.1.0.

The function MyVISEDG in SWDRAW_ShapeAnalysis.cxx is removed as it does not seem to do anything useful and relevant DRAW command K_VISEDG is never used in tests.
2019-10-30 23:26:08 +03:00
abv
53d770b3a2 0031092: Foundation Classes - incorrect last output value for Infinite progress indicator
DRAW implementation of progress indicator is corrected to print "finished" instead of 1e100 for the end of infinite range.
Added test bugs fclasses bug31092
2019-10-30 23:23:55 +03:00
abv
7ed6e985e2 0013175: XCAF document with one vertex is exported to an incorrect STEP file
Added non-regression test case
2019-10-30 23:23:54 +03:00
oan
da6b95a075 0031043: GCPnts_TangentialDeflection generates points which number is inconsistent with MinimumOfPoints Parameter
Updated crvtpoints command API to reproduce reported problem
Generate number of points according to the specified minimum value
2019-10-29 11:04:53 +03:00
kgv
565baee64b 0031070: Configuration - fix building issues when using Emscripten toolchain
Handled __EMSCRIPTEN__ macros to:
- Workaround atomics (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is undefined, but GCC atomics are provided).
- Suppress non-standard header <sys/signal.h> warning.
- Return OSD_LinuxREDHAT.
- Avoid inclusion of XLib headers.
- Skip fontconfig library.
- Enable EGL+GLES path (translated by Emscripten into WebGL).
- Skip eglCreatePbufferSurface() not implemented by Emscripten EGL.

Fixed Graphic3d_Vec4.hxx usage within Quantity_ColorRGBA.hxx.

OpenGl_ShaderManager::defaultGlslVersion() now prefers GLSL 300 es when WebGL 2.0 is available,
as there no any OpenGL ES greater than 3.0 emulation so far.

Shaders_Declarations.glsl - added workaround for GLSL compilation on WebGL 1.0
by defining Light properties accessors as macros instead of functions
('[]' : Index expression must be constant).

OpenGl_FrameBuffer::Init() - added workaround for initialization of GL_DEPTH24_STENCIL8
depth-stencil attachment on WebGL 1.0 + GL_WEBGL_depth_texture extension.

OpenGl_Context::Vec4FromQuantityColor() now considers myIsSRgbActive flag
to handle use case, when Immediate Layer is drawn directly into window buffer,
which is not sRGB-ready.

Added new sample - OCCT WebGL viewer.
2019-10-27 00:43:07 +03:00
kgv
36e28f96f6 0031079: Visualization - embed minimal fallback font
Font_FTFont::FindAndCreate() now loads embedded fallback font within Font_StrictLevel_Any level.
Font_FontMgr::FindFont() - fixed misprint in message, and customized message for range fallback error.
Font_FontMgr - added one more fallback Korean font for Linux.

vfont command has been extended with options to clear Font Manager content.
2019-10-27 00:43:06 +03:00
kgv
215dd33149 0031102: Visualization, AIS_ViewController - AIS_DragAction_Stop is never emitted on mouse unclick
AIS_ViewController::UpdateMousePosition() now sets myMouseStopDragOnUnclick flag
to emit AIS_DragAction_Stop on mouse unclick.
2019-10-27 00:43:05 +03:00
emv
5646c90e87 0030878: Modeling Algorithms - BRepLib_MakeFace produces face with abnormal surface
When collecting the points to build plane use the points on the curve instead of poles (in case of BSpline and Bezier curves).

Side effect changes:
Changes in Geom2dHatch_Elements are to increase the chance of correct 2d classification (by the means of Geom2dHatch_Classifier) by taking more than just one point on the edge to construct the classification ray and by checking if this ray is not tangent to the edge itself.
2019-10-24 17:47:28 +03:00
kgv
97e0059b05 0031088: Visualization - GL_INVALID_ENUM while dumping view within OpenGL 1.1
OpenGl_Sampler::resetGlobalTextureParams() - added missing version check before disabling GL_POINT_SPRITE.
2019-10-24 17:45:00 +03:00
kgv
8445efca81 0031082: Visualization - crash on display if there are no lights in the view
OpenGl_View - fixed uninitialized property myLights.
2019-10-24 17:43:38 +03:00
kgv
a6a66c3a21 0031037: Foundation Classes - add class Message_PrinterSystemLog for printing messages into system log
Added new class Message_PrinterSystemLog that can be used for logging messages into system log for debugging application in restricted environment.
2019-10-22 15:17:00 +03:00
kgv
cc99be369e 0025341: Visualization - disallow displaying object as part of connected one and as a free one at the same time
AIS_ConnectedInteractive::connect() now throws exception on connecting already displayed object.
AIS_TextLabel::AcceptDisplayMode() - added missing Display Mode filter.

Commands vconnect, vconnectto and vaddconnected have been corrected to
replace dispalyed AIS_Shape with AIS_ConnectedInteractive in context.
2019-10-22 15:15:56 +03:00
kgv
1a5007a920 0031067: Visualization - Aspect_Window::DoResize() should be a non-const method
Removed 'const' from Aspect_Window::DoResize() virtual method.
2019-10-22 15:15:55 +03:00
kgv
3818aacaa5 0031056: Samples - update glfw sample to use AIS_ViewController 2019-10-22 15:15:54 +03:00
kgv
e1d039d56d 0031036: Foundation Classes, Message_PrinterOStream - add option printing colored text into console
New property Message_PrinterOStream::ToColorize() can be set to colorize text output into console.
The new option is disabled by default.
2019-10-22 15:15:53 +03:00
kgv
a4815d5509 0029902: Data Exchange, XCAF - provide extended Material definition for visualization purposes
Introduced new attribute XCAFDoc_VisMaterial storing visualization material definition.

XCAFPrs_Style has been exteneded Material() property.
XCAFPrs_AISObject::DispatchStyles() maps new XCAFPrs_Style::Material() property onto graphics aspects.

RWGltf_GltfJsonParser and RWObj_CafReader now put Material definition into XCAF document instead of a color label.
RWGltf_MaterialMetallicRoughness - added missing properties AlphaMode, AlphaCutOff and IsDoubleSided;
fixed default values in constructor for Metallic and Roughness.

Added commands XGetAllVisMaterials, XGetVisMaterial, XAddVisMaterial,
XRemoveVisMaterial, XSetVisMaterial, XUnsetVisMaterial for working with
new visualization materials table in the document.
2019-10-22 15:15:53 +03:00
kgv
ba00aab7a0 0029528: Visualization, TKOpenGl - allow defining sRGB textures
OpenGL rendering is now done into sRGB framebuffer.
OpenGl_ShaderManager::prepareStdProgramFboBlit() has been extended
by programs resolving MSAA texture and applying gamma correction as fallbacks.

Quantity_Color definition has been modified to store RGB components
in linear color space within Quantity_TOC_RGB type.
Standard colors defined by Quantity_NameOfColor enumeration has been updated accordingly.
New Quantity_TOC_sRGB type has been introduced to handle RGB components in non-linear sRGB color space.

OpenGl_TextureFormat class definition has been moved to dedicated files.
New method OpenGl_TextureFormat::FindFormat() replaces OpenGl_Texture::GetDataFormat().
New method OpenGl_TextureFormat::FindSizedFormat() replaces OpenGl_FrameBuffer::getColorDataFormat()
and OpenGl_FrameBuffer::getDepthDataFormat().

Graphic3d_TextureRoot::IsColorMap() - introduced new property defining
if RGB(A)8 image formats should be loaded as sRGB(A) textures or as data RGB(A) textures.
OpenGl_Texture initialization methods have been extended with new theIsColorMap argument.

vreadpixel - added argument -sRGB printing color in sRGB color space.

Test cases have been updated to new sRGB rendered results.
2019-10-22 15:15:52 +03:00
kgv
aaf8d6a98d 0030969: Coding Rules - refactor Quantity_Color.cxx color table definition
The table of named colors has been compressed and moved out
from Quantity_Color.cxx into Quantity_ColorTable.pxx.

Quantity_NameOfColor - grayscale enumeration values have been re-ordered to fix discontinuity.
Duplicating colors has been merged within enumeration:
  CHARTREUSE=CHARTREUSE1, GOLD=GOLD1, GREEN=GREEN1, ORANGE=ORANGE1,
  ORANGERED=ORANGERED1, RED=RED1, TOMATO=TOMATO1, YELLOW=YELLOW1.
Added aliases to several other common colors:
  BLUE=BLUE1, CYAN=CYAN1, LIGHTCYAN=LIGHTCYAN1, MAGENTA=MAGENTA1.

Quantity_Color class definition has been cleaned to follow OCCT coding style.
Quantity_Color now stores NCollection_Vec3<float> as class field instead of separate components.
Removed unused class Quantity_ColorDefinitionError.

New methods Quantity_Color::Convert_LinearRGB_To_sRGB() and Quantity_Color::Convert_sRGB_To_LinearRGB()
converting RGB components from linear to non-linear sRGB colorspace and vice versa.
Image_PixMap::PixelColor() and Image_PixMap::SetPixelColor() methods have been extended
with an optional argument for performing linearization/delinearization of 8-bit sRGB pixel formats.

Draw Harness command AISColor has been corrected to take color name instead of enumeration index.
2019-10-22 15:15:51 +03:00
jgv
b008226203 0031023: Fillet regression in OCCT 7.4 from 7.3
Modify local static function ReorderFaces to be able to process multiple-faces-connecting vertices.
2019-10-22 15:15:50 +03:00
jgv
eff3eff916 0030940: BRepFilletAPI_MakeFillet algorithm fails on closed shell
1. Add check of configuration of corner in the end of spine.
2. Correct treatment of "smooth corners".
2019-10-22 15:15:49 +03:00
jgv
bf327822d6 0026071: BRepOffsetAPI_MakePipeShell produces rough result
1. Correct building history: the case of closed spine.
2. Rollback method GeomFill_CorrectedFrenet::InitInterval - correct processing singularities on spine.
3. Correct test cases.
2019-10-22 15:15:48 +03:00
jgv
63da0df9c2 0031066: Infinite loop in ShapeUpgrade_UnifySameDomain
Modification in local static method TransformPCurves - compute real U And V bounds of a face and use them in further computations.
2019-10-22 15:15:47 +03:00
skl
13a44c4b7f 0029068: Data Exchange - Invalid rotation of result shape after import attached STEP file
Changes for using Axis Placement(not used during creation of assembly) as transformation for root Shape Representation.
Test for bug 29068 and auxilary command are added.
2019-10-22 15:15:46 +03:00
aml
f04de1335c 0030932: Modeling Algorithms - Invalid result on 2d curve on surface approximation
New method generating 3D curve is added when 2D curve is linear isoline.
2019-10-22 15:15:46 +03:00
emv
c08fd12706 0029843: Modeling Algorithms - Boolean FUSE produces incorrect result
When splitting the shell/face with internal faces/edges use the 'internal' criteria of the face to choose the way to create loops.

Side effect changes:
- When performing Boolean operation - move the objects located far from Origin to the Origin to increase the accuracy of intersections.
2019-10-22 15:15:45 +03:00
ifv
d7992a77f6 0031029: BRepLib::SameParameter regression in OCCT 7.4 from OCCT 7.3
1. BRepLib.cxx: calculation of 2d tolerance is changed in method BRepLib::SameParameter(Edge..)
2. Geom2dConvert.cxx: incorrect comparing
"SquareDistance < tolerance"
is replaced by
"SquareDistance < tolerance*tolerance"
because tolerance is linear value.
2019-10-22 15:15:44 +03:00
kgv
8c787b5fa9 0031050: Data Exchange - XmlXCAF persistence stores triangulation-only Faces without any geometry
BRepTools_ShapeSet now ignores myWithTriangles flag in case if triangulation is the only geometry representation.
2019-10-22 15:15:43 +03:00
ifv
44fafc477f 0031031: Incorrect result is returned from BRepPrimAPI_MakePrism::Generated()
1. src\BRepSweep\BRepSweep_NumLinearRegularSweep.cxx

Fix bug by adding result in list of generated shapes, if initial shape is vertex, edge or face.

2. src\BRepLib\BRepLib.cxx

Add protection against treatment not geometric edge in BRepLib::UpdateInnerTolerances(...)

3. Add test case for bug and correct test for bug 30346 according to new behavior of algorithm
2019-10-22 15:15:43 +03:00
vro
780fbc2897 0031013: Application Framework - Storage status is wrong after a failure
CDF_StoreList.cxx::Store() was amended
2019-10-22 15:15:42 +03:00
apn
620a6baa59 0030456: Make OCCT_CHECK_AND_UNSET_GROUP more general
Modify OCCT_CHECK_AND_UNSET_GROUP function to allow unset any group of variables
2019-10-22 15:15:41 +03:00
kgv
89073268fd 0031021: Coding Rules - Deprecation warnings on OSX within Draw_Window_1.mm
Use new renamed enumeration values instead of deprecated ones.
2019-10-22 15:15:40 +03:00
abv
6ed44b1ca9 0031044: Coding - Standard_NODISCARD should be placed before Standard_EXPORT
Standard_NODISCARD is put before Standard_EXPORT in all places throughout OCCT code
2019-10-22 12:12:26 +03:00
msv
746cb7c328 0031020: Coding - invalid inline usage in BRepBlend_AppSurface
BRepBlend_AppSurface and some other classes have been corrected to avoid inlining member functions in .cxx code.
2019-10-22 12:12:25 +03:00
kgv
8ba3d978db 0031048: Visualization - runtime error reported by Clang undefined behavior sanitizer in Image_AlienPixMap::Save()
Image_PixMapData - use unsigned math (uintptr_t) instead of signed math with pointers for defining negative stride.
2019-10-19 22:59:21 +03:00
abv
c275673dbf 0030993: Modeling Algorithms - heap-use-after-free reported by Clang address sanitizer in BRepFeat_MakeRevolutionForm::Perform()
Use of reference to object removed from the list after that removal is avoided
2019-10-19 12:31:38 +03:00
abv
9e3045dae1 0030992: Foundation Classes - heap-buffer-overflow reported by Clang address sanitizer in BSplCLib::BuildKnots()
Inconsistent code for guessing bspline span index is removed in Geom_OsculatingSurface::BuildOsculatingSurface().
2019-10-19 12:31:38 +03:00
kgv
c2bcd98369 0031024: Coding - invalid left shift in BVH_RadixSorter::Perform() using -fsanitize=undefined
Standard_Integer has been replaced by unsigned int for bit operations.
2019-10-19 12:31:37 +03:00
abv
683b72c3c1 0031010: Foundation Classes - heap-buffer-overflow reported by Clang address sanitizer in OSD_Path::IsUncExtendedPath()
Use of memcmp is replaced by strncmp to avoid possible read access out of string buffer size
2019-10-19 12:31:36 +03:00
mpv
3358ed643b 0031008: Application Framework - memcpy-param-overlap reported by Clang address sanitizer in LDOM_XmlReader::ReadRecord()
Use memmove instead of memcpy because of copy of the possible overlapped source and destination parts of the buffer.
2019-10-19 12:31:35 +03:00
abv
2724a0b3cc 0031034: Visualization - stack-use-after-scope reported by Clang address sanitizer in AIS_FixRelation::Compute()
Methods of classes Geom_ElementarySurface, Geom_Conic, and Geom2d_Conic setting or returning values of fields are made inline and return const& to avoid copying
2019-10-19 12:31:35 +03:00
abv
0deeff45a0 Update version of OCCT up to 7.4.1 2019-10-19 12:31:33 +03:00
1070 changed files with 22411 additions and 12766 deletions

View File

@@ -108,6 +108,7 @@ else()
elseif (ANDROID)
set (CSF_ThreadLibs "c")
set (CSF_OpenGlLibs "EGL GLESv2")
set (CSF_androidlog "log")
elseif (UNIX)
set (CSF_ThreadLibs "pthread rt stdc++")
if (USE_GLES2)

View File

@@ -12,18 +12,12 @@ macro (OCCT_CHECK_AND_UNSET VARNAME)
endif()
endmacro()
macro (OCCT_CHECK_AND_UNSET_GROUP VARNAME)
OCCT_CHECK_AND_UNSET ("${VARNAME}_DIR")
OCCT_CHECK_AND_UNSET ("${VARNAME}_INCLUDE_DIR")
OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY")
OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY_DIR")
if (WIN32)
OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL")
OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL_DIR")
endif()
macro (OCCT_CHECK_AND_UNSET_GROUP GROUPNAME)
get_cmake_property(VARS VARIABLES)
string (REGEX MATCHALL "(^|;)${GROUPNAME}[A-Za-z0-9_]*" GROUPNAME_VARS "${VARS}")
foreach(GROUPNAME_VAR ${GROUPNAME_VARS})
OCCT_CHECK_AND_UNSET(${GROUPNAME_VAR})
endforeach()
endmacro()
macro (OCCT_CHECK_AND_UNSET_INSTALL_DIR_SUBDIRS)

View File

@@ -1419,6 +1419,9 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
set aFrmsMap(CSF_TclTkLibs) "Tk"
set aLibsMap(CSF_TclTkLibs) ""
set aLibsMap(CSF_QT) "QtCore QtGui"
} elseif { "$theOS" == "android" } {
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
set aLibsMap(CSF_androidlog) "log"
} else {
set aLibsMap(CSF_fontconfig) "fontconfig"
if { "$theOS" == "qnx" } {

View File

@@ -14,6 +14,7 @@ overview/overview.md
../samples/qt/AndroidQt/ReadMe.md
../samples/java/jniviewer/ReadMe.md
../samples/ios/UIKitSample/ReadMe.md
../samples/webgl/ReadMe.md
tutorial/tutorial.md

View File

@@ -1857,8 +1857,6 @@ The following API changes have been made:
@subsection upgrade_740_stdnamespace Standard_Stream.hxx no more has "using std::" statements
*Standard_Stream.hxx* header, commonly included by other OCCT header files, does no more add entities from *std namespace* related to streams (like *std::cout*, *std::istream* and others) into global namespace.
The application code relying on this matter should be updated to either specify std namespace explicitly (like std::cout) or add "using std::" statements locally.
<<<<<<< HEAD
=======
@section upgrade_occt750 Upgrade to OCCT 7.5.0
@@ -1890,17 +1888,3 @@ Unexpected const-ness of Aspect_Window::DoResize() method has been removed, so t
@subsection upgrade_750_rename Renaming of types
Enumeration BRepOffset_Type is renamed to ChFiDS_TypeOfConcavity.
@subsection upgrade_750_sensitiveEntity Select3D_SensitiveEntity interface change
The method Select3D_SensitiveEntity::NbSubElements() has been changed to be constant. Select3D_SensitiveEntity subclasses at application level should be updated accordingly.
@subsection upgrade_750_Booleans Changes in Boolean operations algorithm
* TreatCompound method has been moved from *BOPAlgo_Tools* to *BOPTools_AlgoTools*. Additionally, the map parameter became optional:
~~~~
void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLS,
TopTools_MapOfShape* theMap = NULL);
~~~~

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -153,6 +153,9 @@ on this tool.
**RapidJSON** is an Open Source JSON parser and generator for C++.
RapidJSON is optionally used by OCCT for reading glTF files (https://rapidjson.org/).
**DejaVu** fonts are a font family based on the Vera Fonts under a permissive license (MIT-like, https://dejavu-fonts.github.io/License.html).
DejaVu Sans (basic Latin sub-set) is used by OCCT as fallback font when no system font is available.
Adobe Systems, Inc. provides **Adobe Reader**, which can be used to view files in Portable Document Format (PDF).
@section OCCT_OVW_SECTION_3 Documentation
@@ -211,6 +214,7 @@ for which OCCT is certified to work.
| Linux | GNU gcc 4.3+ <br> LLVM CLang 3.6+ |
| OS X / macOS | XCode 6 or newer |
| Android | NDK r10, GNU gcc 4.8 or newer |
| Web | Emscripten SDK 1.39 or newer (CLang) |
1) VC++ 141 64-bit is used for regular testing and for building binary package of official release of OCCT on Windows.
@@ -569,3 +573,11 @@ There is a sample demonstrating usage of OCCT on iOS with Apple UIKit framework.
@figure{/overview/images/sample_ios_uikit.png}
See \subpage occt_samples_ios_uikit "iOS sample Readme" for details.
@subsubsection OCCT_OVW_SECTION_7_3_6 Web
WebGL Viewer sample demonstrating usage of OCCT 3D Viewer in Web browser with Emscripten SDK can be found in `samples/webgl`.
@figure{/overview/images/sample_webgl.png}
See \subpage occt_samples_webgl "WebGL sample Readme" for details.

View File

@@ -35,13 +35,49 @@
#include <GLFW/glfw3.h>
namespace
{
//! Convert GLFW mouse button into Aspect_VKeyMouse.
static Aspect_VKeyMouse mouseButtonFromGlfw (int theButton)
{
switch (theButton)
{
case GLFW_MOUSE_BUTTON_LEFT: return Aspect_VKeyMouse_LeftButton;
case GLFW_MOUSE_BUTTON_RIGHT: return Aspect_VKeyMouse_RightButton;
case GLFW_MOUSE_BUTTON_MIDDLE: return Aspect_VKeyMouse_MiddleButton;
}
return Aspect_VKeyMouse_NONE;
}
//! Convert GLFW key modifiers into Aspect_VKeyFlags.
static Aspect_VKeyFlags keyFlagsFromGlfw (int theFlags)
{
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
if ((theFlags & GLFW_MOD_SHIFT) != 0)
{
aFlags |= Aspect_VKeyFlags_SHIFT;
}
if ((theFlags & GLFW_MOD_CONTROL) != 0)
{
aFlags |= Aspect_VKeyFlags_CTRL;
}
if ((theFlags & GLFW_MOD_ALT) != 0)
{
aFlags |= Aspect_VKeyFlags_ALT;
}
if ((theFlags & GLFW_MOD_SUPER) != 0)
{
aFlags |= Aspect_VKeyFlags_META;
}
return aFlags;
}
}
// ================================================================
// Function : GlfwOcctView
// Purpose :
// ================================================================
GlfwOcctView::GlfwOcctView()
: myCurAction3d (CurAction3d_Nothing),
myToRedraw (true)
{
}
@@ -193,15 +229,7 @@ void GlfwOcctView::mainloop()
glfwWaitEvents();
if (!myView.IsNull())
{
if (myView->IsInvalidated())
{
myView->Redraw();
}
else if (myToRedraw)
{
myView->RedrawImmediate();
}
myToRedraw = false;
FlushViewEvents (myContext, myView, true);
}
}
}
@@ -237,7 +265,6 @@ void GlfwOcctView::onResize (int theWidth, int theHeight)
myView->MustBeResized();
myView->Invalidate();
myView->Redraw();
//myToRedraw = true;
}
}
@@ -247,13 +274,10 @@ void GlfwOcctView::onResize (int theWidth, int theHeight)
// ================================================================
void GlfwOcctView::onMouseScroll (double theOffsetX, double theOffsetY)
{
if (myView.IsNull()) { return; }
const Graphic3d_Vec2i aPos = myOcctWindow->CursorPosition();
myView->StartZoomAtPoint (aPos.x(), aPos.y());
myView->ZoomAtPoint (0, 0, int(theOffsetY * 4.0), int(theOffsetY * 4.0));
myView->Invalidate();
myToRedraw = true;
if (!myView.IsNull())
{
UpdateZoom (Aspect_ScrollDelta (myOcctWindow->CursorPosition(), int(theOffsetY * 8.0)));
}
}
// ================================================================
@@ -265,27 +289,13 @@ void GlfwOcctView::onMouseButton (int theButton, int theAction, int theMods)
if (myView.IsNull()) { return; }
const Graphic3d_Vec2i aPos = myOcctWindow->CursorPosition();
if (theAction != GLFW_PRESS)
if (theAction == GLFW_PRESS)
{
myCurAction3d = CurAction3d_Nothing;
return;
PressMouseButton (aPos, mouseButtonFromGlfw (theButton), keyFlagsFromGlfw (theMods), false);
}
myMouseMin = aPos;
myMouseMax = aPos;
switch (theButton)
else
{
case GLFW_MOUSE_BUTTON_RIGHT:
{
myCurAction3d = CurAction3d_DynamicRoation;
myView->StartRotation (aPos.x(), aPos.y());
break;
}
case GLFW_MOUSE_BUTTON_MIDDLE:
{
myCurAction3d = CurAction3d_DynamicPanning;
break;
}
ReleaseMouseButton (aPos, mouseButtonFromGlfw (theButton), keyFlagsFromGlfw (theMods), false);
}
}
@@ -295,30 +305,9 @@ void GlfwOcctView::onMouseButton (int theButton, int theAction, int theMods)
// ================================================================
void GlfwOcctView::onMouseMove (int thePosX, int thePosY)
{
if (myView.IsNull()) { return; }
switch (myCurAction3d)
const Graphic3d_Vec2i aNewPos (thePosX, thePosY);
if (!myView.IsNull())
{
case CurAction3d_DynamicRoation:
{
myView->Rotation (thePosX, thePosY);
myView->Invalidate();
myToRedraw = true;
break;
}
case CurAction3d_DynamicPanning:
{
myView->Pan (thePosX - myMouseMax.x(), -(thePosY - myMouseMax.y()));
myView->Invalidate();
myToRedraw = true;
myMouseMax.SetValues (thePosX, thePosY);
break;
}
default:
{
myContext->MoveTo (thePosX, thePosY, myView, false);
myToRedraw = true;
break;
}
UpdateMousePosition (aNewPos, PressedMouseButtons(), LastMouseFlags(), false);
}
}

View File

@@ -25,20 +25,12 @@
#include "GlfwOcctWindow.h"
#include <AIS_InteractiveContext.hxx>
#include <AIS_ViewController.hxx>
#include <V3d_View.hxx>
//! Sample class creating 3D Viewer within GLFW window.
class GlfwOcctView
class GlfwOcctView : protected AIS_ViewController
{
public:
enum CurAction3d
{
CurAction3d_Nothing,
CurAction3d_DynamicZooming,
CurAction3d_DynamicPanning,
CurAction3d_DynamicRoation
};
public:
//! Default constructor.
GlfwOcctView();
@@ -115,11 +107,6 @@ private:
Handle(V3d_View) myView;
Handle(AIS_InteractiveContext) myContext;
CurAction3d myCurAction3d;
Graphic3d_Vec2i myMouseMin;
Graphic3d_Vec2i myMouseMax;
bool myToRedraw;
};
#endif // _GlfwOcctView_Header

View File

@@ -134,17 +134,17 @@ void GlfwOcctWindow::Unmap() const
// Function : DoResize
// Purpose :
// ================================================================
Aspect_TypeOfResize GlfwOcctWindow::DoResize() const
Aspect_TypeOfResize GlfwOcctWindow::DoResize()
{
if (glfwGetWindowAttrib (myGlfwWindow, GLFW_VISIBLE) == 1)
{
int anXPos = 0, anYPos = 0, aWidth = 0, aHeight = 0;
glfwGetWindowPos (myGlfwWindow, &anXPos, &anYPos);
glfwGetWindowSize(myGlfwWindow, &aWidth, &aHeight);
*const_cast<Standard_Integer*>(&myXLeft ) = anXPos;
*const_cast<Standard_Integer*>(&myXRight ) = anXPos + aWidth;
*const_cast<Standard_Integer*>(&myYTop ) = anYPos;
*const_cast<Standard_Integer*>(&myYBottom) = anYPos + aHeight;
myXLeft = anXPos;
myXRight = anXPos + aWidth;
myYTop = anYPos;
myYBottom = anYPos + aHeight;
}
return Aspect_TOR_UNKNOWN;
}

View File

@@ -65,7 +65,7 @@ public:
virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return 0; }
//! Applies the resizing to the window <me>
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE;
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
//! Returns True if the window <me> is opened and False if the window is closed.
virtual Standard_Boolean IsMapped() const Standard_OVERRIDE;

View File

@@ -44,7 +44,7 @@ public:
virtual void Unmap() const Standard_OVERRIDE {}
//! Applies the resizing to the window <me>
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
//! Apply the mapping change to the window <me>
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }

View File

@@ -216,8 +216,7 @@ void GeomSources::DisplaySurface(CGeometryDoc* aDoc,
void GeomSources::ResetView(CGeometryDoc* aDoc)
{
aDoc->GetAISContext()->CurrentViewer()->InitActiveViews();
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveView();
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveViews().First();
aView->Reset();
}

View File

@@ -68,8 +68,7 @@ void TexturesExt_Presentation::DoSample()
void TexturesExt_Presentation::Init()
{
// initialize v3d_view so it displays TexturesExt well
getViewer()->InitActiveViews();
Handle(V3d_View) aView = getViewer()->ActiveView();
Handle(V3d_View) aView = getViewer()->ActiveViews().First();
aView->SetSize(ZVIEW_SIZE);
// getDocument()->UpdateResultMessageDlg("Textured Shape",

View File

@@ -1020,8 +1020,7 @@ void CViewer3dDoc::OnDumpView()
pView->UpdateWindow();
}
myViewer->InitActiveViews();
Handle(V3d_View) aView = myViewer->ActiveView();
Handle(V3d_View) aView = myViewer->ActiveViews().First();
ExportView (aView);
}

View File

@@ -1012,65 +1012,61 @@ aParams.NbMsaaSamples = aParams.NbMsaaSamples == 0 ? 8 : 0;\n\
GetDocument()->UpdateResultMessageDlg("SetAntialiasingOn/SetAntialiasingOff",Message);
}
void CViewer3dView::OnClearLights()
void CViewer3dView::OnClearLights()
{
// Setting Off all viewer active lights
TColStd_ListOfTransient lights;
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())
// Setting Off all viewer active lights
V3d_ListOfLight lights;
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())
{
lights.Append(myView->Viewer()->ActiveLight());
lights.Append (anIter.Value());
}
TColStd_ListIteratorOfListOfTransient itrLights(lights);
V3d_ListOfLightIterator itrLights(lights);
for (; itrLights.More(); itrLights.Next())
{
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
myView->Viewer()->SetLightOff(light);
myView->Viewer()->SetLightOff (itrLights.Value());
}
// Setting Off all view active lights
// Setting Off all view active lights
lights.Clear();
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())
{
lights.Append(myView->ActiveLight());
lights.Append (anIter.Value());
}
itrLights.Initialize(lights);
itrLights.Initialize (lights);
for (; itrLights.More(); itrLights.Next())
{
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
myView->SetLightOff(light);
myView->SetLightOff (itrLights.Value());
}
myView->Viewer()->SetDefaultLights();// Setting the default lights on
myView->Viewer()->SetDefaultLights(); // Setting the default lights on
NbActiveLights = 2;// There are 2 default active lights
NbActiveLights = 2; // There are 2 default active lights
myView->Update();
myView->Update();
TCollection_AsciiString Message("\
// Setting Off all viewer active lights\n\
TColStd_ListOfTransient lights;\n\
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())\n\
// Setting Off all viewer active lights\n\
V3d_ListOfLight lights;\n\
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
{\n\
lights.Append(myView->Viewer()->ActiveLight());\n\
lights.Append (anIter.Value());\n\
}\n\
TColStd_ListIteratorOfListOfTransient itrLights(lights);\n\
V3d_ListOfLightIterator itrLights(lights);\n\
for (; itrLights.More(); itrLights.Next())\n\
{\n\
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
myView->Viewer()->SetLightOff(light);\n\
myView->Viewer()->SetLightOff (itrLights.Value())\n\
}\n\
\n\
// Setting Off all view active lights\n\
// Setting Off all view active lights\n\
lights.Clear();\n\
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())\n\
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
{\n\
lights.Append(myView->ActiveLight());\n\
lights.Append (anIter.Value());\n\
}\n\
itrLights.Initialize(lights);\n\
for (; itrLights.More(); itrLights.Next())\n\
{\n\
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
myView->SetLightOff(light);\n\
myView->SetLightOff (itrLights.Value());\n\
}\n\
\n\
myView->Viewer()->SetDefaultLights();// Setting the default lights on\n\

View File

@@ -413,8 +413,7 @@ void CTriangulationDoc::OnDumpView()
pView->UpdateWindow();
}
myViewer->InitActiveViews();
Handle(V3d_View) aView = myViewer->ActiveView();
Handle(V3d_View) aView = myViewer->ActiveViews().First();
ExportView (aView);
}

View File

@@ -230,8 +230,7 @@ void COCCDemoDoc::OnDumpView()
pView->UpdateWindow();
}
myViewer->InitActiveViews();
Handle(V3d_View) aView = myViewer->ActiveView();
Handle(V3d_View) aView = myViewer->ActiveViews().First();
ExportView (aView);
}

View File

@@ -489,8 +489,7 @@ void OCC_3dBaseDoc::OnUpdateV3dButtons (CCmdUI* pCmdUI)
// Common function to change raytracing params and redraw view
void OCC_3dBaseDoc::OnObjectRayTracingAction()
{
myAISContext->CurrentViewer()->InitActiveViews();
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveView();
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveViews().First();
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
if (myRayTracingIsOn)
aParams.Method = Graphic3d_RM_RAYTRACING;

View File

@@ -44,7 +44,7 @@ public:
virtual void Unmap() const {}
//! Applies the resizing to the window <me>
virtual Aspect_TypeOfResize DoResize() const { return Aspect_TOR_UNKNOWN; }
virtual Aspect_TypeOfResize DoResize() { return Aspect_TOR_UNKNOWN; }
//! Apply the mapping change to the window <me>
virtual Standard_Boolean DoMapping() const { return Standard_True; }

View File

@@ -81,7 +81,7 @@ void OcctWindow::Unmap() const
// function : DoResize
// purpose :
// =======================================================================
Aspect_TypeOfResize OcctWindow::DoResize() const
Aspect_TypeOfResize OcctWindow::DoResize()
{
int aMask = 0;
Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
@@ -126,10 +126,10 @@ Aspect_TypeOfResize OcctWindow::DoResize() const
break;
} // end switch
*( ( Standard_Integer* )&myXLeft ) = myWidget->rect().left();
*( ( Standard_Integer* )&myXRight ) = myWidget->rect().right();
*( ( Standard_Integer* )&myYTop ) = myWidget->rect().top();
*( ( Standard_Integer* )&myYBottom) = myWidget->rect().bottom();
myXLeft = myWidget->rect().left();
myXRight = myWidget->rect().right();
myYTop = myWidget->rect().top();
myYBottom = myWidget->rect().bottom();
}
return aMode;

View File

@@ -51,7 +51,7 @@ public:
virtual Aspect_Drawable NativeParentHandle() const;
//! Applies the resizing to the window <me>
virtual Aspect_TypeOfResize DoResize() const;
virtual Aspect_TypeOfResize DoResize();
//! Returns True if the window <me> is opened
//! and False if the window is closed.

View File

@@ -276,7 +276,7 @@ blend result _model 2 _model_161
# Show result
pload VISUALIZATION
vinit Driver1/Viewer1/View1
vbackground -color 0.784314 0.784314 1
vbackground -color C8C8FF
vdisplay -dispMode 1 result
vfit
vaspects result -setFaceBoundaryDraw 1 -mostContinuity c2

View File

@@ -262,7 +262,7 @@ unifysamedom result p_1
# Show result
pload VISUALIZATION
vinit Driver1/Viewer1/View1
vbackground -color 0.784314 0.784314 1
vbackground -color C8C8FF
vdisplay -dispMode 1 result
vfit
vaspects result -setFaceBoundaryDraw 1

View File

@@ -68,18 +68,18 @@ vlight add directional direction 0 -10 0 head 1 color white
vdisplay b1 b2 b3 b4 b5 b6 b7 b8 b9 b10
# set colors like in boxes of on OCC logo
vsetcolor b1 0.8671875 0 0.16015625
vsetcolor b2 0.96484375 0.8671875 0
vsetcolor b3 0.609375 0.97734375 0.09375
vsetcolor b4 0.90234375 0 0.48046875
vsetcolor b5 0 0.48046875 0.73828125
vsetcolor b6 0.578125 0 0.48046875
vsetcolor b7 0.93359375 0.609375 0
vsetcolor b8 0 0.70703125 0.9296875
vsetcolor b9 0 0.64453125 0.48046875
vsetcolor b10 0 0.48046875 0.73828125
vsetcolor b1 DD0029
vsetcolor b2 F6DD00
vsetcolor b3 98F918
vsetcolor b4 E9007A
vsetcolor b5 007ABC
vsetcolor b6 93007A
vsetcolor b7 EE9800
vsetcolor b8 00B489
vsetcolor b9 00A47A
vsetcolor b10 007ABC
# set material to plastic for better look
for {set i 1} {$i <= 10} {incr i} {vsetmaterial b$i plastic}
vdrawtext label "Which\nbox\nis\ncloser\nto\nyou?" -pos 0 -6 -2 -color 0 0 0 -halign left -valign bottom -angle 0 -zoom 0 -height 40
vdrawtext label "Which\nbox\nis\ncloser\nto\nyou?" -pos 0 -6 -2 -color BLACK -halign left -valign bottom -angle 0 -zoom 0 -height 40

View File

@@ -255,27 +255,27 @@ if [info exists i7_show_3dview] {
vlight add directional direction 1 -1 -2 head 1
vdisplay case
vsetcolor case 0.7 0.7 0.7
vsetcolor case GRAY70
vdisplay title
vsetcolor title 0.1 0.1 0.1
vsetcolor title GRAY10
# board is mostly yellow (edges, triangle markers)
foreach f [explode board f] { vdisplay $f; vsetcolor $f 0.7 0.5 0.3 }
foreach f [explode board f] { vdisplay $f; vsetcolor $f B3803D }
# top and bottom faces are light-green (outside) and dark-green (inside)
vsetcolor board_4 0 0.6 0.55
vsetcolor board_5 0 0.6 0.55
vsetcolor board_12 0 0.3 0.33
vsetcolor board_14 0 0.3 0.33
vsetcolor board_4 00998C
vsetcolor board_5 00998C
vsetcolor board_12 004D54
vsetcolor board_14 004D54
vdisplay rpads
vsetcolor rpads 0.7 0.6 0.4
vsetcolor rpads B39966
vdisplay bpads
vsetcolor bpads 0.7 0.6 0.4
vsetcolor bpads B39966
vdisplay brpk
vsetcolor brpk 0.5 0.4 0.3
vsetcolor brpk 80664D
donly board case rpads brpk; fit
}
@@ -287,17 +287,17 @@ pload OCAF XDE
NewDocument D MDTV-XCAF
SetName D [XAddShape D board 0] "Board"
foreach f [explode board f] { XSetColor D $f 0.7 0.5 0.3 }
XSetColor D board_4 0 0.6 0.55
XSetColor D board_5 0 0.6 0.55
XSetColor D board_12 0 0.3 0.33
XSetColor D board_14 0 0.3 0.33
foreach f [explode board f] { XSetColor D $f B3803D }
XSetColor D board_4 00998C
XSetColor D board_5 00998C
XSetColor D board_12 004D54
XSetColor D board_14 004D54
SetName D [XAddShape D case 0] "Case"
XSetColor D case 0.7 0.7 0.7
XSetColor D case GRAY70
SetName D [XAddShape D title 0] "Case title"
XSetColor D title 0.1 0.1 0.1
XSetColor D title GRAY10
SetName D [XAddShape D rpads 1] "Top side contact pads"
SetName D [XAddShape D bpads 1] "Bottom contact pads"
@@ -306,17 +306,17 @@ SetName D [XFindShape D rpad] "Round pad"
SetName D [XFindShape D Rpad] "Big round pad"
SetName D [XFindShape D spad_1] "Square pad 1"
SetName D [XFindShape D spad_2] "Square pad 2"
XSetColor D rpad 0.7 0.6 0.4
XSetColor D Rpad 0.7 0.6 0.4
XSetColor D bpad 0.7 0.6 0.4
XSetColor D spad_1 0.7 0.6 0.4
XSetColor D spad_2 0.7 0.6 0.4
XSetColor D rpad B39966
XSetColor D Rpad B39966
XSetColor D bpad B39966
XSetColor D spad_1 B39966
XSetColor D spad_2 B39966
SetName D [XAddShape D brpk 1] "Bottom packages"
SetName D [XFindShape D rpk] "Bottom package"
XSetColor D rpk1 0.7 0.7 0.7
XSetColor D rpk2 0.5 0.4 0.3
XSetColor D rpk3 0.7 0.7 0.7
XSetColor D rpk1 GRAY70
XSetColor D rpk2 80664D
XSetColor D rpk3 GRAY70
XShow D
vlight clear

View File

@@ -36,9 +36,7 @@ set anArrAngle [expr 3.14 * 12.0 / 180.0]
# Form dimension names list to set parameters with vdimparam command
set aList {rd_1 rd_2 ad_1 ad_2 ad_3}
for {set i 1} {$i <= 10} {incr i} {
lappend aList ld_$i
}
for {set i 1} {$i <= 10} {incr i} { lappend aList ld_$i }
puts "Creating dimensions..."
vdimension ld_1 -length -shapes bs_27 -plane xoy -color black -flyout -15
@@ -67,29 +65,14 @@ foreach i $aList {
vfit
puts "Displaying exported shapes..."
vdisplay a b
vsetdispmode a 1
vsetdispmode b 1
vdisplay -dispMode 1 a b
vaspects a -setmaterial steel
vaspects b -setmaterial bronze
puts "Clipping shapes for better view..."
vclipplane create pa
vclipplane change pa equation 0 0 1 0
vclipplane change pa capping on
vclipplane change pa capping color 0.9 0.9 0.9
vclipplane set pa object a
vclipplane create pb
vclipplane change pb equation 0 0 1 0
vclipplane change pb capping on
vclipplane change pb capping color 1.0 0.8 0.0
vclipplane set pb object b
vclipplane change pa capping texname $aHatch
vclipplane change pa capping texscale 0.05 -0.05
vclipplane change pb capping texname $aHatch
vclipplane change pb capping texscale 0.05 0.05
vclipplane pa -set a -equation 0 0 1 0 -capping on -color GRAY90 -texName $aHatch -texScale 0.05 -0.05
vclipplane pb -set b -equation 0 0 1 0 -capping on -color GOLD -texName $aHatch -texScale 0.05 -0.05
vbottom
vrotate -0.3 -0.3 0

View File

@@ -77,14 +77,13 @@ SetName D $main "OCC Logo 2019"
SetName D [XFindShape D sb] "Core"
SetName D [XFindShape D tp] "Loop"
SetName D [XFindShape D rs] "Connector"
XSetColor D sb 1 0.21 0.32
XSetColor D tp 0 0.667 0.855
XSetColor D rs 0 0.45 0.69
XSetColor D sb FF3652
XSetColor D tp 00AADA
XSetColor D rs 0073B0
# display
vinit
vsetcolorbg 1 1 1
vsetdispmode 1
XDisplay D
vinit View1
vbackground -color WHITE
XDisplay -dispMode 1 D
vtop
vfit

View File

@@ -56,7 +56,7 @@ for { set aMarkerType 0 } { $aMarkerType <= 13 } { incr aMarkerType } {
set aRow [expr $aMarkerType - 7]
set aCol 5
set aName [lindex $aMarkerTypeNames $aMarkerType]
vdrawtext "$aName" "$aName" -pos 0 [expr $aRow + 0.5] 0 -color 0.5 1.0 1.0 -halign center -valign center -angle 000 -zoom 0 -height 12 -aspect bold -font $aLabelFont -noupdate
vdrawtext "$aName" "$aName" -pos 0 [expr $aRow + 0.5] 0 -color 7FFFFF -halign center -valign center -angle 000 -zoom 0 -height 12 -aspect bold -font $aLabelFont -noupdate
vdisplay -top -noupdate "$aName"
if { $aMarkerType == 13 } {
vmarkerstest m${aMarkerType}_${aCol} $aCol $aRow 0 PointsOnSide=1 FileName=$aCustom1

View File

@@ -4,36 +4,22 @@
#Title: Material properties in viewer
set THE_MATERIALS {brass bronze copper gold jade neon_phc pewter obsidian plaster plastic satin silver steel stone chrome aluminium water glass diamond charcoal}
set THE_COLORS {default red green blue1}
set THE_COLORS {default red green blue}
set THE_ROW_DIST 35
proc drawLabels {} {
set x 20
set y 15
set r 0.098
set g 0.098
set b 0.098
foreach aMatIter $::THE_MATERIALS {
vdrawtext "$aMatIter" "$aMatIter" -pos $x $y 0 -color $r $g $b -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
vdrawtext "$aMatIter" "$aMatIter" -pos $x $y 0 -color GRAY10 -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
incr y 10
}
set x 40
set y 5
foreach aColIter $::THE_COLORS {
if { $aColIter == "red" } {
set r 1.0
set g 0.0
set b 0
} elseif { $aColIter == "green" } {
set r 0.0
set g 1.0
set b 0.0
} elseif { $aColIter == "blue1" } {
set r 0.0
set g 0.0
set b 1.0
}
vdrawtext "$aColIter" "$aColIter" -pos $x $y 0 -color $r $g $b -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
set aLabColor "$aColIter"
if { "$aColIter" == "default" } { set aLabColor BLACK }
vdrawtext "$aColIter" "$aColIter" -pos $x $y 0 -color "$aLabColor" -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
incr x $::THE_ROW_DIST
}
}
@@ -69,7 +55,7 @@ vclose ALL
vinit View1 w=768 h=768
vtop
vglinfo
vbackground -gradient 0.705882 0.784314 1 0.705882 0.705882 0.705882 -gradientMode VERTICAL
vbackground -gradient B4C8FF B4B4B4 -gradientMode VERTICAL
vlight -change 0 -dir 0.577 -0.577 -0.577
vrenderparams -msaa 8

View File

@@ -46,18 +46,17 @@ NewDocument D
XAddShape D body_1
XAddShape D core_1
#XSetColor D body_1 0. 0. 1.
for {set i 1} {$i <= 26} {incr i} {XSetColor D body_1_$i 0. 0. 1.}
XSetColor D body_1_1 0.9 0.5 0.4
XSetColor D body_1_9 0.9 0.5 0.4
for {set i 10} {$i <= 22} {incr i} {XSetColor D body_1_$i 0.6 0.7 0.0}
XSetColor D core_1 0.1 0.1 1.
foreach ff [explode core_1 f] { XSetColor D $ff 0.1 0.1 1. ; puts "set color $ff" }
XShow D
for {set i 1} {$i <= 26} {incr i} {XSetColor D body_1_$i BLUE}
XSetColor D body_1_1 E68066
XSetColor D body_1_9 E68066
for {set i 10} {$i <= 22} {incr i} {XSetColor D body_1_$i 99B300}
XSetColor D core_1 1A1AFF
foreach ff [explode core_1 f] { XSetColor D $ff 1A1AFF ; puts "set color $ff" }
vclear
vinit View1
XDisplay -dispMode 1 D -explore
vfit
vsetdispmode 1
vrenderparams -msaa 8
vbackground -color WHITE

View File

@@ -121,21 +121,21 @@ eval compound [explode mass w] mass
compound sample occ name material sheets scale mass text
compound snowflake lines text drawing
bounding snowflake -save x1 y1 z1 x2 y2 z2
# display in 3d view
vinit Driver1/Viewer1/View1 w=1024 h=768
vdisplay snowflake lines text
vrenderparams -msaa 8
vsetcolor snowflake BLACK
vsetcolor lines BLACK
vsetcolor text BLACK
vsetcolor snowflake 0 0 0
vsetcolor lines 0 0 0
vsetcolor text 0 0 0
vbackground -color WHITE
vtop
vfit
# add dimension:
# detect vertices extremal in X direction
bounding snowflake -save x1 y1 z1 x2 y2 z2
plane f1 x1 0 0 1 0 0
plane f2 x2 0 0 1 0 0
mkface f1 f1
@@ -159,3 +159,7 @@ for {set i 1} {$i <= 2} {incr i} {
}
}
vdimension length -length -shapes $v1 $v2 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
if { [regexp HAVE_GL2PS [dversion]] } {
puts "You can use command vexport to generate PDF: vexport your_file_path.pdf"
}

View File

@@ -28,19 +28,20 @@ SetName D [XFindShape D link]:2 "Nut instance 1"
SetName D [XFindShape D link]:3 "Nut instance 2"
puts "- Pin will be white"
XSetColor D [XFindShape D pin] 1 1 1
XSetColor D [XFindShape D pin] WHITE
puts "- Nut itself will be dark gray"
XSetColor D [XFindShape D nut] 0.1 0.1 0.1
XSetColor D [XFindShape D nut] GRAY10
puts "- Nut instance #1 will be red"
XSetColor D [XFindShape D link]:2 1 0 0
XSetColor D [XFindShape D link]:2 RED
puts "- Nut instance #2 will be green"
XSetColor D [XFindShape D link]:3 0 1 0
XSetColor D [XFindShape D link]:3 GREEN
puts "Starting DF browser..."
DFBrowse D
puts "Expand the document tree to see its structure and assigned names"
puts "Showing assembly in 3d view..."
XShow D
vclear
vinit View1
XDisplay -dispMode 1 D -explore
vfit
vsetdispmode 1

2
samples/webgl/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/build
/work

View File

@@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.2)
project(occt-webgl-sample)
set(CMAKE_CXX_STANDARD 11)
set(APP_VERSION_MAJOR 1)
set(APP_VERSION_MINOR 0)
set(APP_TARGET occt-webgl-sample)
# customize build
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_WEBGL2=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s SAFE_HEAP=1")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_EXIT_RUNTIME=1")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s TOTAL_MEMORY=16MB")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ABORTING_MALLOC=0")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s FORCE_FILESYSTEM=1")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --preload-file myFile")
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
file(GLOB SOURCES
*.h
*.cpp
)
source_group ("Headers" FILES
WasmOcctView.h)
source_group ("Sources" FILES
WasmOcctView.cpp
main.cpp)
# FreeType
find_package(freetype REQUIRED NO_DEFAULT_PATH)
if(freetype_FOUND)
message (STATUS "Using FreeType from \"${freetype_DIR}\"" )
else()
message(WARNING "Could not find FreeType, please set freetype_DIR variable." )
endif()
# Open CASCADE Technology
find_package(OpenCASCADE REQUIRED NO_DEFAULT_PATH)
if(OpenCASCADE_FOUND)
message (STATUS "Using OpenCASCADE from \"${OpenCASCADE_DIR}\"" )
INCLUDE_DIRECTORIES(${OpenCASCADE_INCLUDE_DIR})
LINK_DIRECTORIES(${OpenCASCADE_LIBRARY_DIR})
else()
message(WARNING "Could not find OpenCASCADE, please set OpenCASCADE_DIR variable." )
set(OCCT_LIBRARY_DIR)
set(OCCT_BIN_DIR)
endif()
set(OpenCASCADE_LIBS TKRWMesh TKBinXCAF TKBin TKBinL TKOpenGl TKXCAF TKVCAF TKCAF TKV3d TKHLR TKMesh TKService TKShHealing TKPrim TKTopAlgo TKGeomAlgo TKBRep TKGeomBase TKG3d TKG2d TKMath TKLCAF TKCDF TKernel)
add_executable(${APP_TARGET} ${SOURCES})
target_link_libraries(
${APP_TARGET}
${OpenCASCADE_LIBS}
freetype
)
set_target_properties(${APP_TARGET} PROPERTIES LINK_FLAGS "-s EXPORTED_FUNCTIONS=['_main','_onFileDataRead'] -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']")
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.wasm DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES occt-webgl-sample.html DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES ${OpenCASCADE_RESOURCE_DIR}/DrawResources/OCC_logo.png DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES ${OpenCASCADE_RESOURCE_DIR}/DrawResources/lamp.ico DESTINATION ${CMAKE_INSTALL_PREFIX})

28
samples/webgl/ReadMe.md Normal file
View File

@@ -0,0 +1,28 @@
OCCT WebGL Viewer sample {#occt_samples_webgl}
==================
This sample demonstrates simple way of using OCCT libraries in Web application written in C++ and translated into WebAssembly module using Emscripten SDK (emsdk):
https://emscripten.org/
Sample consists of the Open CASCADE 3D Viewer with a button for opening a model in BREP format.
The sample requires a WebGL 2.0 capable browser supporting WebAssembly 1.0 (Wasm).
Installation and configuration:
1. Install Emscripten SDK and activate minimal configuration (Python, Java and CLang) following *emsdk* documentation. Activate also MinGW when building sample on Windows host.
2. Build (using *emsdk*) or download FreeType static library.
3. Configure CMake for building Open CASCADE Technology (OCCT) static libraries (BUILD_LIBRARY_TYPE="Static").
For this, activate *emsdk* command prompt, configure CMake for building OCCT using cross-compilation toolchain, disable *BUILD_MODULE_Draw*.
4. Perform building and installation steps.
~~~~~
> ${EMSDK}/fastcomp/emscripten/cmake/Modules/Platform/Emscripten.cmake
~~~~~
5. Configure CMake for building this WebGL sample using *emsdk* with paths to OCCT and FreeType. Perform building and installation steps.
6. Copy data/occ/Ball.brep from OCCT into "samples" folder within WebGL sample installation path.
7. Navigate to installation folder and start web server from it; Python coming with *emsdk* can be used for this purpose:
~~~~~
> python -m SimpleHTTPServer 8080
~~~~~
8. Open compatible browser and enter path taking into account your web server settings:
~~~~~
> http://localhost:8080/occt-webgl-sample.html
~~~~~

View File

@@ -0,0 +1,678 @@
// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of the examples of the Open CASCADE Technology software library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
#include "WasmOcctView.h"
#include "WasmVKeys.h"
#include <AIS_Shape.hxx>
#include <AIS_ViewCube.hxx>
#include <Aspect_Handle.hxx>
#include <Aspect_DisplayConnection.hxx>
#include <Aspect_NeutralWindow.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <Prs3d_DatumAspect.hxx>
#include <iostream>
#define THE_CANVAS_ID "canvas"
namespace
{
EM_JS(int, jsCanvasGetWidth, (), {
return canvas.width;
});
EM_JS(int, jsCanvasGetHeight, (), {
return canvas.height;
});
EM_JS(float, jsDevicePixelRatio, (), {
var aDevicePixelRatio = window.devicePixelRatio || 1;
return aDevicePixelRatio;
});
//! Return cavas size in pixels.
static Graphic3d_Vec2i jsCanvasSize()
{
return Graphic3d_Vec2i (jsCanvasGetWidth(), jsCanvasGetHeight());
}
}
// ================================================================
// Function : WasmOcctView
// Purpose :
// ================================================================
WasmOcctView::WasmOcctView()
: myDevicePixelRatio (1.0f),
myUpdateRequests (0)
{
}
// ================================================================
// Function : ~WasmOcctView
// Purpose :
// ================================================================
WasmOcctView::~WasmOcctView()
{
}
// ================================================================
// Function : run
// Purpose :
// ================================================================
void WasmOcctView::run()
{
initWindow();
initViewer();
initDemoScene();
if (myView.IsNull())
{
return;
}
myView->MustBeResized();
myView->Redraw();
// There is no inifinite message loop, main() will return from here immediately.
// Tell that our Module should be left loaded and handle events through callbacks.
//emscripten_set_main_loop (redrawView, 60, 1);
//emscripten_set_main_loop (redrawView, -1, 1);
EM_ASM(Module['noExitRuntime'] = true);
}
// ================================================================
// Function : initWindow
// Purpose :
// ================================================================
void WasmOcctView::initWindow()
{
myDevicePixelRatio = jsDevicePixelRatio();
myCanvasId = THE_CANVAS_ID;
const char* aTargetId = !myCanvasId.IsEmpty() ? myCanvasId.ToCString() : NULL;
const EM_BOOL toUseCapture = EM_TRUE;
emscripten_set_resize_callback (NULL, this, toUseCapture, onResizeCallback);
emscripten_set_mousedown_callback (NULL, this, toUseCapture, onMouseCallback);
emscripten_set_mouseup_callback (NULL, this, toUseCapture, onMouseCallback);
emscripten_set_mousemove_callback (NULL, this, toUseCapture, onMouseCallback);
emscripten_set_dblclick_callback (aTargetId, this, toUseCapture, onMouseCallback);
emscripten_set_click_callback (aTargetId, this, toUseCapture, onMouseCallback);
emscripten_set_mouseenter_callback (aTargetId, this, toUseCapture, onMouseCallback);
emscripten_set_mouseleave_callback (aTargetId, this, toUseCapture, onMouseCallback);
emscripten_set_wheel_callback (aTargetId, this, toUseCapture, onWheelCallback);
emscripten_set_touchstart_callback (aTargetId, this, toUseCapture, onTouchCallback);
emscripten_set_touchend_callback (aTargetId, this, toUseCapture, onTouchCallback);
emscripten_set_touchmove_callback (aTargetId, this, toUseCapture, onTouchCallback);
emscripten_set_touchcancel_callback(aTargetId, this, toUseCapture, onTouchCallback);
//emscripten_set_keypress_callback (NULL, this, toUseCapture, onKeyCallback);
emscripten_set_keydown_callback (NULL, this, toUseCapture, onKeyDownCallback);
emscripten_set_keyup_callback (NULL, this, toUseCapture, onKeyUpCallback);
}
// ================================================================
// Function : dumpGlInfo
// Purpose :
// ================================================================
void WasmOcctView::dumpGlInfo (bool theIsBasic)
{
TColStd_IndexedDataMapOfStringString aGlCapsDict;
myView->DiagnosticInformation (aGlCapsDict, theIsBasic ? Graphic3d_DiagnosticInfo_Basic : Graphic3d_DiagnosticInfo_Complete);
if (theIsBasic)
{
TCollection_AsciiString aViewport;
aGlCapsDict.FindFromKey ("Viewport", aViewport);
aGlCapsDict.Clear();
aGlCapsDict.Add ("Viewport", aViewport);
}
aGlCapsDict.Add ("Display scale", TCollection_AsciiString(myDevicePixelRatio));
// beautify output
{
TCollection_AsciiString* aGlVer = aGlCapsDict.ChangeSeek ("GLversion");
TCollection_AsciiString* aGlslVer = aGlCapsDict.ChangeSeek ("GLSLversion");
if (aGlVer != NULL
&& aGlslVer != NULL)
{
*aGlVer = *aGlVer + " [GLSL: " + *aGlslVer + "]";
aGlslVer->Clear();
}
}
TCollection_AsciiString anInfo;
for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aGlCapsDict); aValueIter.More(); aValueIter.Next())
{
if (!aValueIter.Value().IsEmpty())
{
if (!anInfo.IsEmpty())
{
anInfo += "\n";
}
anInfo += aValueIter.Key() + ": " + aValueIter.Value();
}
}
::Message::DefaultMessenger()->Send (anInfo, Message_Warning);
}
// ================================================================
// Function : initPixelScaleRatio
// Purpose :
// ================================================================
void WasmOcctView::initPixelScaleRatio()
{
SetTouchToleranceScale (myDevicePixelRatio);
if (!myView.IsNull())
{
myView->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
}
if (!myContext.IsNull())
{
myContext->SetPixelTolerance (int(myDevicePixelRatio * 6.0));
if (!myViewCube.IsNull())
{
static const double THE_CUBE_SIZE = 60.0;
myViewCube->SetSize (myDevicePixelRatio * THE_CUBE_SIZE, false);
myViewCube->SetBoxFacetExtension (myViewCube->Size() * 0.15);
myViewCube->SetAxesPadding (myViewCube->Size() * 0.10);
myViewCube->SetFontHeight (THE_CUBE_SIZE * 0.16);
if (myViewCube->HasInteractiveContext())
{
myContext->Redisplay (myViewCube, false);
}
}
}
}
// ================================================================
// Function : initViewer
// Purpose :
// ================================================================
bool WasmOcctView::initViewer()
{
// Build with "--preload-file MyFontFile.ttf" option
// and register font in Font Manager to use custom font(s).
/*const char* aFontPath = "MyFontFile.ttf";
if (Handle(Font_SystemFont) aFont = Font_FontMgr::GetInstance()->CheckFont (aFontPath))
{
Font_FontMgr::GetInstance()->RegisterFont (aFont, true);
}
else
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: font '") + aFontPath + "' is not found", Message_Fail);
}*/
Handle(Aspect_DisplayConnection) aDisp;
Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (aDisp, false);
aDriver->ChangeOptions().buffersNoSwap = true; // swap has no effect in WebGL
if (!aDriver->InitContext())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: EGL initialization failed"), Message_Fail);
return false;
}
Handle(V3d_Viewer) aViewer = new V3d_Viewer (aDriver);
aViewer->SetComputedMode (false);
aViewer->SetDefaultShadingModel (Graphic3d_TOSM_FRAGMENT);
aViewer->SetDefaultLights();
aViewer->SetLightOn();
Handle(Aspect_NeutralWindow) aWindow = new Aspect_NeutralWindow();
Graphic3d_Vec2i aWinSize = jsCanvasSize();
if (aWinSize.x() < 10 || aWinSize.y() < 10)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning: invalid canvas size"), Message_Warning);
}
aWindow->SetSize (aWinSize.x(), aWinSize.y());
myTextStyle = new Prs3d_TextAspect();
myTextStyle->SetFont (Font_NOF_ASCII_MONO);
myTextStyle->SetHeight (12);
myTextStyle->Aspect()->SetColor (Quantity_NOC_GRAY95);
myTextStyle->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
myTextStyle->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
myTextStyle->Aspect()->SetTextFontAspect (Font_FA_Bold);
myTextStyle->Aspect()->SetTextZoomable (false);
myTextStyle->SetHorizontalJustification (Graphic3d_HTA_LEFT);
myTextStyle->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
myView = new V3d_View (aViewer);
myView->SetImmediateUpdate (false);
myView->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
myView->ChangeRenderingParams().ToShowStats = true;
myView->ChangeRenderingParams().StatsTextAspect = myTextStyle->Aspect();
myView->ChangeRenderingParams().StatsTextHeight = (int )myTextStyle->Height();
myView->SetWindow (aWindow);
dumpGlInfo (false);
myContext = new AIS_InteractiveContext (aViewer);
initPixelScaleRatio();
return true;
}
// ================================================================
// Function : initDemoScene
// Purpose :
// ================================================================
void WasmOcctView::initDemoScene()
{
if (myContext.IsNull())
{
return;
}
//myView->TriedronDisplay (Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_WIREFRAME);
myViewCube = new AIS_ViewCube();
// presentation parameters
initPixelScaleRatio();
myViewCube->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_RIGHT_LOWER, Graphic3d_Vec2i (100, 100)));
myViewCube->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
myViewCube->Attributes()->DatumAspect()->SetTextAspect (myTextStyle);
// animation parameters
myViewCube->SetViewAnimation (myViewAnimation);
myViewCube->SetFixedAnimationLoop (false);
myViewCube->SetAutoStartAnimation (true);
myContext->Display (myViewCube, false);
// Build with "--preload-file MySampleFile.brep" option to load some shapes here.
}
// ================================================================
// Function : updateView
// Purpose :
// ================================================================
void WasmOcctView::updateView()
{
if (!myView.IsNull())
{
if (++myUpdateRequests == 1)
{
emscripten_async_call (onRedrawView, this, 0);
}
}
}
// ================================================================
// Function : redrawView
// Purpose :
// ================================================================
void WasmOcctView::redrawView()
{
if (!myView.IsNull())
{
FlushViewEvents (myContext, myView, true);
}
}
// ================================================================
// Function : handleViewRedraw
// Purpose :
// ================================================================
void WasmOcctView::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
const Handle(V3d_View)& theView)
{
myUpdateRequests = 0;
AIS_ViewController::handleViewRedraw (theCtx, theView);
if (myToAskNextFrame)
{
// ask more frames
++myUpdateRequests;
emscripten_async_call (onRedrawView, this, 0);
}
}
// ================================================================
// Function : onResizeEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onResizeEvent (int theEventType, const EmscriptenUiEvent* theEvent)
{
(void )theEventType; // EMSCRIPTEN_EVENT_RESIZE or EMSCRIPTEN_EVENT_CANVASRESIZED
(void )theEvent;
if (myView.IsNull())
{
return EM_FALSE;
}
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast (myView->Window());
Graphic3d_Vec2i aWinSizeOld, aWinSizeNew (jsCanvasSize());
if (aWinSizeNew.x() < 10 || aWinSizeNew.y() < 10)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning: invalid canvas size"), Message_Warning);
}
aWindow->Size (aWinSizeOld.x(), aWinSizeOld.y());
const float aPixelRatio = jsDevicePixelRatio();
if (aWinSizeNew != aWinSizeOld
|| aPixelRatio != myDevicePixelRatio)
{
if (myDevicePixelRatio != aPixelRatio)
{
myDevicePixelRatio = aPixelRatio;
initPixelScaleRatio();
}
aWindow->SetSize (aWinSizeNew.x(), aWinSizeNew.y());
myView->MustBeResized();
myView->Invalidate();
myView->Redraw();
dumpGlInfo (true);
}
return EM_TRUE;
}
// ================================================================
// Function : onMouseEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onMouseEvent (int theEventType, const EmscriptenMouseEvent* theEvent)
{
if (myView.IsNull())
{
return EM_FALSE;
}
Graphic3d_Vec2i aWinSize;
myView->Window()->Size (aWinSize.x(), aWinSize.y());
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (theEvent->canvasX, theEvent->canvasY));
Aspect_VKeyFlags aFlags = 0;
if (theEvent->ctrlKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_CTRL; }
if (theEvent->shiftKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_SHIFT; }
if (theEvent->altKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_ALT; }
if (theEvent->metaKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_META; }
const bool isEmulated = false;
const Aspect_VKeyMouse aButtons = WasmVKeys_MouseButtonsFromNative (theEvent->buttons);
switch (theEventType)
{
case EMSCRIPTEN_EVENT_MOUSEMOVE:
{
if ((aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
&& PressedMouseButtons() == Aspect_VKeyMouse_NONE)
{
return EM_FALSE;
}
if (UpdateMousePosition (aNewPos, aButtons, aFlags, isEmulated))
{
updateView();
}
break;
}
case EMSCRIPTEN_EVENT_MOUSEDOWN:
case EMSCRIPTEN_EVENT_MOUSEUP:
{
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
{
return EM_FALSE;
}
if (UpdateMouseButtons (aNewPos, aButtons, aFlags, isEmulated))
{
updateView();
}
break;
}
case EMSCRIPTEN_EVENT_CLICK:
case EMSCRIPTEN_EVENT_DBLCLICK:
{
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
{
return EM_FALSE;
}
break;
}
case EMSCRIPTEN_EVENT_MOUSEENTER:
{
break;
}
case EMSCRIPTEN_EVENT_MOUSELEAVE:
{
// there is no SetCapture() support, so that mouse unclick events outside canvas will not arrive,
// so we have to forget current state...
if (UpdateMouseButtons (aNewPos, Aspect_VKeyMouse_NONE, aFlags, isEmulated))
{
updateView();
}
break;
}
}
return EM_TRUE;
}
// ================================================================
// Function : onWheelEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onWheelEvent (int theEventType, const EmscriptenWheelEvent* theEvent)
{
if (myView.IsNull()
|| theEventType != EMSCRIPTEN_EVENT_WHEEL)
{
return EM_FALSE;
}
Graphic3d_Vec2i aWinSize;
myView->Window()->Size (aWinSize.x(), aWinSize.y());
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (theEvent->mouse.canvasX, theEvent->mouse.canvasY));
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
{
return EM_FALSE;
}
double aDelta = 0.0;
switch (theEvent->deltaMode)
{
case DOM_DELTA_PIXEL:
{
aDelta = theEvent->deltaY / (5.0 * myDevicePixelRatio);
break;
}
case DOM_DELTA_LINE:
{
aDelta = theEvent->deltaY * 8.0;
break;
}
case DOM_DELTA_PAGE:
{
aDelta = theEvent->deltaY >= 0.0 ? 24.0 : -24.0;
break;
}
}
if (UpdateZoom (Aspect_ScrollDelta (aNewPos, -aDelta)))
{
updateView();
}
return EM_TRUE;
}
// ================================================================
// Function : onTouchEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onTouchEvent (int theEventType, const EmscriptenTouchEvent* theEvent)
{
const double aClickTolerance = 5.0;
if (myView.IsNull())
{
return EM_FALSE;
}
Graphic3d_Vec2i aWinSize;
myView->Window()->Size (aWinSize.x(), aWinSize.y());
bool hasUpdates = false;
for (int aTouchIter = 0; aTouchIter < theEvent->numTouches; ++aTouchIter)
{
const EmscriptenTouchPoint& aTouch = theEvent->touches[aTouchIter];
if (!aTouch.isChanged)
{
continue;
}
const Standard_Size aTouchId = (Standard_Size )aTouch.identifier;
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (aTouch.canvasX, aTouch.canvasY));
switch (theEventType)
{
case EMSCRIPTEN_EVENT_TOUCHSTART:
{
if (aNewPos.x() >= 0 && aNewPos.x() < aWinSize.x()
&& aNewPos.y() >= 0 && aNewPos.y() < aWinSize.y())
{
hasUpdates = true;
AddTouchPoint (aTouchId, Graphic3d_Vec2d (aNewPos));
myClickTouch.From.SetValues (-1.0, -1.0);
if (myTouchPoints.Extent() == 1)
{
myClickTouch.From = Graphic3d_Vec2d (aNewPos);
}
}
break;
}
case EMSCRIPTEN_EVENT_TOUCHMOVE:
{
const int anOldIndex = myTouchPoints.FindIndex (aTouchId);
if (anOldIndex != 0)
{
hasUpdates = true;
UpdateTouchPoint (aTouchId, Graphic3d_Vec2d (aNewPos));
if (myTouchPoints.Extent() == 1
&& (myClickTouch.From - Graphic3d_Vec2d (aNewPos)).cwiseAbs().maxComp() > aClickTolerance)
{
myClickTouch.From.SetValues (-1.0, -1.0);
}
}
break;
}
case EMSCRIPTEN_EVENT_TOUCHEND:
case EMSCRIPTEN_EVENT_TOUCHCANCEL:
{
if (RemoveTouchPoint (aTouchId))
{
if (myTouchPoints.IsEmpty()
&& myClickTouch.From.minComp() >= 0.0)
{
if (myDoubleTapTimer.IsStarted()
&& myDoubleTapTimer.ElapsedTime() <= myMouseDoubleClickInt)
{
myView->FitAll (0.01, false);
myView->Invalidate();
}
else
{
myDoubleTapTimer.Stop();
myDoubleTapTimer.Reset();
myDoubleTapTimer.Start();
SelectInViewer (Graphic3d_Vec2i (myClickTouch.From), false);
}
}
hasUpdates = true;
}
break;
}
}
}
if (hasUpdates)
{
updateView();
}
return hasUpdates || !myTouchPoints.IsEmpty() ? EM_TRUE : EM_FALSE;
}
// ================================================================
// Function : onKeyDownEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onKeyDownEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent)
{
if (myView.IsNull()
|| theEventType != EMSCRIPTEN_EVENT_KEYDOWN) // EMSCRIPTEN_EVENT_KEYPRESS
{
return EM_FALSE;
}
const double aTimeStamp = EventTime();
const Aspect_VKey aVKey = WasmVKeys_VirtualKeyFromNative (theEvent->keyCode);
if (aVKey == Aspect_VKey_UNKNOWN)
{
return EM_FALSE;
}
if (theEvent->repeat == EM_FALSE)
{
myKeys.KeyDown (aVKey, aTimeStamp);
}
if (Aspect_VKey2Modifier (aVKey) == 0)
{
// normal key
}
return EM_FALSE;
}
// ================================================================
// Function : onKeyUpEvent
// Purpose :
// ================================================================
EM_BOOL WasmOcctView::onKeyUpEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent)
{
if (myView.IsNull()
|| theEventType != EMSCRIPTEN_EVENT_KEYUP)
{
return EM_FALSE;
}
const double aTimeStamp = EventTime();
const Aspect_VKey aVKey = WasmVKeys_VirtualKeyFromNative (theEvent->keyCode);
if (aVKey == Aspect_VKey_UNKNOWN)
{
return EM_FALSE;
}
if (theEvent->repeat == EM_TRUE)
{
return EM_FALSE;
}
const unsigned int aModif = myKeys.Modifiers();
myKeys.KeyUp (aVKey, aTimeStamp);
if (Aspect_VKey2Modifier (aVKey) == 0)
{
// normal key released
switch (aVKey | aModif)
{
case Aspect_VKey_F:
{
myView->FitAll (0.01, false);
myView->Invalidate();
updateView();
return EM_TRUE;
}
}
}
return EM_FALSE;
}

View File

@@ -0,0 +1,157 @@
// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of the examples of the Open CASCADE Technology software library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
#ifndef _WasmOcctView_HeaderFile
#define _WasmOcctView_HeaderFile
#include <AIS_InteractiveContext.hxx>
#include <AIS_ViewController.hxx>
#include <V3d_View.hxx>
#include <emscripten.h>
#include <emscripten/html5.h>
class AIS_ViewCube;
//! Sample class creating 3D Viewer within Emscripten canvas.
class WasmOcctView : protected AIS_ViewController
{
public:
//! Default constructor.
WasmOcctView();
//! Destructor.
virtual ~WasmOcctView();
//! Main application entry point.
void run();
//! Return interactive context.
const Handle(AIS_InteractiveContext)& Context() const { return myContext; }
//! Return view.
const Handle(V3d_View)& View() const { return myView; }
//! Return device pixel ratio for handling high DPI displays.
float DevicePixelRatio() const { return myDevicePixelRatio; }
private:
//! Create window.
void initWindow();
//! Create 3D Viewer.
bool initViewer();
//! Fill 3D Viewer with a DEMO items.
void initDemoScene();
//! Application event loop.
void mainloop();
//! Request view redrawing.
void updateView();
//! Flush events and redraw view.
void redrawView();
//! Handle view redraw.
virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
const Handle(V3d_View)& theView) override;
//! Dump WebGL context information.
void dumpGlInfo (bool theIsBasic);
//! Initialize pixel scale ratio.
void initPixelScaleRatio();
//! Return point from logical units to backing store.
Graphic3d_Vec2d convertPointToBacking (const Graphic3d_Vec2d& thePnt) const
{
return thePnt * myDevicePixelRatio;
}
//! Return point from logical units to backing store.
Graphic3d_Vec2i convertPointToBacking (const Graphic3d_Vec2i& thePnt) const
{
Graphic3d_Vec2d aPnt = Graphic3d_Vec2d (thePnt) * myDevicePixelRatio + Graphic3d_Vec2d (0.5);
return Graphic3d_Vec2i (aPnt);
}
//! @name Emscripten callbacks
private:
//! Window resize event.
EM_BOOL onResizeEvent (int theEventType, const EmscriptenUiEvent* theEvent);
//! Mouse event.
EM_BOOL onMouseEvent (int theEventType, const EmscriptenMouseEvent* theEvent);
//! Scroll event.
EM_BOOL onWheelEvent (int theEventType, const EmscriptenWheelEvent* theEvent);
//! Touch event.
EM_BOOL onTouchEvent (int theEventType, const EmscriptenTouchEvent* theEvent);
//! Key down event.
EM_BOOL onKeyDownEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent);
//! Key up event.
EM_BOOL onKeyUpEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent);
//! @name Emscripten callbacks (static functions)
private:
static EM_BOOL onResizeCallback (int theEventType, const EmscriptenUiEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onResizeEvent (theEventType, theEvent); }
static void onRedrawView (void* theView)
{ return ((WasmOcctView* )theView)->redrawView(); }
static EM_BOOL onMouseCallback (int theEventType, const EmscriptenMouseEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onMouseEvent (theEventType, theEvent); }
static EM_BOOL onWheelCallback (int theEventType, const EmscriptenWheelEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onWheelEvent (theEventType, theEvent); }
static EM_BOOL onTouchCallback (int theEventType, const EmscriptenTouchEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onTouchEvent (theEventType, theEvent); }
static EM_BOOL onKeyDownCallback (int theEventType, const EmscriptenKeyboardEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onKeyDownEvent (theEventType, theEvent); }
static EM_BOOL onKeyUpCallback (int theEventType, const EmscriptenKeyboardEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onKeyUpEvent (theEventType, theEvent); }
private:
Handle(AIS_InteractiveContext) myContext; //!< interactive context
Handle(V3d_View) myView; //!< 3D view
Handle(Prs3d_TextAspect) myTextStyle; //!< text style for OSD elements
Handle(AIS_ViewCube) myViewCube; //!< view cube object
TCollection_AsciiString myCanvasId; //!< canvas element id on HTML page
Aspect_Touch myClickTouch; //!< single touch position for handling clicks
OSD_Timer myDoubleTapTimer; //!< timer for handling double tap
float myDevicePixelRatio; //!< device pixel ratio for handling high DPI displays
unsigned int myUpdateRequests; //!< counter for unhandled update requests
};
#endif // _WasmOcctView_HeaderFile

264
samples/webgl/WasmVKeys.h Normal file
View File

@@ -0,0 +1,264 @@
// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of the examples of the Open CASCADE Technology software library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
#ifndef _WasmVKeys_HeaderFile
#define _WasmVKeys_HeaderFile
#include <Aspect_VKey.hxx>
#include <emscripten/key_codes.h>
//! Convert Emscripten mouse buttons into Aspect_VKeyMouse.
inline Aspect_VKeyMouse WasmVKeys_MouseButtonsFromNative (unsigned short theButtons)
{
Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
if ((theButtons & 0x1) != 0)
{
aButtons |= Aspect_VKeyMouse_LeftButton;
}
if ((theButtons & 0x2) != 0)
{
aButtons |= Aspect_VKeyMouse_RightButton;
}
if ((theButtons & 0x4) != 0)
{
aButtons |= Aspect_VKeyMouse_MiddleButton;
}
return aButtons;
}
//! Convert DOM virtual key into Aspect_VKey.
inline Aspect_VKey WasmVKeys_VirtualKeyFromNative (Standard_Integer theKey)
{
if (theKey >= DOM_VK_0
&& theKey <= DOM_VK_9)
{
// numpad keys
return Aspect_VKey((theKey - DOM_VK_0) + Aspect_VKey_0);
}
if (theKey >= DOM_VK_A
&& theKey <= DOM_VK_Z)
{
// main latin alphabet keys
return Aspect_VKey((theKey - DOM_VK_A) + Aspect_VKey_A);
}
if (theKey >= DOM_VK_F1
&& theKey <= DOM_VK_F24)
{
// special keys
if (theKey <= DOM_VK_F12)
{
return Aspect_VKey((theKey - DOM_VK_F1) + Aspect_VKey_F1);
}
return Aspect_VKey_UNKNOWN;
}
if (theKey >= DOM_VK_NUMPAD0
&& theKey <= DOM_VK_NUMPAD9)
{
// numpad keys
return Aspect_VKey((theKey - DOM_VK_NUMPAD0) + Aspect_VKey_Numpad0);
}
switch (theKey)
{
case DOM_VK_CANCEL:
case DOM_VK_HELP:
return Aspect_VKey_UNKNOWN;
case DOM_VK_BACK_SPACE:
return Aspect_VKey_Backspace;
case DOM_VK_TAB:
return Aspect_VKey_Tab;
case DOM_VK_CLEAR:
return Aspect_VKey_UNKNOWN;
case DOM_VK_RETURN:
case DOM_VK_ENTER:
return Aspect_VKey_Enter;
case DOM_VK_SHIFT:
return Aspect_VKey_Shift;
case DOM_VK_CONTROL:
return Aspect_VKey_Control;
case DOM_VK_ALT:
return Aspect_VKey_Alt;
case DOM_VK_PAUSE:
case DOM_VK_CAPS_LOCK:
case DOM_VK_KANA:
//case DOM_VK_HANGUL:
case DOM_VK_EISU:
case DOM_VK_JUNJA:
case DOM_VK_FINAL:
case DOM_VK_HANJA:
//case DOM_VK_KANJI:
return Aspect_VKey_UNKNOWN;
case DOM_VK_ESCAPE:
return Aspect_VKey_Escape;
case DOM_VK_CONVERT:
case DOM_VK_NONCONVERT:
case DOM_VK_ACCEPT:
case DOM_VK_MODECHANGE:
return Aspect_VKey_UNKNOWN;
case DOM_VK_SPACE:
return Aspect_VKey_Space;
case DOM_VK_PAGE_UP:
return Aspect_VKey_PageUp;
case DOM_VK_PAGE_DOWN:
return Aspect_VKey_PageDown;
case DOM_VK_END:
return Aspect_VKey_End;
case DOM_VK_HOME:
return Aspect_VKey_Home;
case DOM_VK_LEFT:
return Aspect_VKey_Left;
case DOM_VK_UP:
return Aspect_VKey_Up;
case DOM_VK_RIGHT:
return Aspect_VKey_Right;
case DOM_VK_DOWN:
return Aspect_VKey_Down;
case DOM_VK_SELECT:
case DOM_VK_PRINT:
case DOM_VK_EXECUTE:
case DOM_VK_PRINTSCREEN:
case DOM_VK_INSERT:
return Aspect_VKey_UNKNOWN;
case DOM_VK_DELETE:
return Aspect_VKey_Delete;
case DOM_VK_COLON:
return Aspect_VKey_Comma;
case DOM_VK_SEMICOLON:
return Aspect_VKey_Semicolon;
case DOM_VK_LESS_THAN:
return Aspect_VKey_UNKNOWN;
case DOM_VK_EQUALS:
return Aspect_VKey_Equal;
case DOM_VK_GREATER_THAN:
return Aspect_VKey_UNKNOWN;
case DOM_VK_QUESTION_MARK:
return Aspect_VKey_Slash;
case DOM_VK_AT: // @ key
return Aspect_VKey_UNKNOWN;
case DOM_VK_WIN:
return Aspect_VKey_Meta;
case DOM_VK_CONTEXT_MENU:
case DOM_VK_SLEEP:
return Aspect_VKey_UNKNOWN;
case DOM_VK_MULTIPLY:
return Aspect_VKey_NumpadMultiply;
case DOM_VK_ADD:
return Aspect_VKey_NumpadAdd;
case DOM_VK_SEPARATOR:
return Aspect_VKey_UNKNOWN;
case DOM_VK_SUBTRACT:
return Aspect_VKey_NumpadSubtract;
case DOM_VK_DECIMAL:
return Aspect_VKey_UNKNOWN;
case DOM_VK_DIVIDE:
return Aspect_VKey_NumpadDivide;
case DOM_VK_NUM_LOCK:
return Aspect_VKey_Numlock;
case DOM_VK_SCROLL_LOCK:
return Aspect_VKey_Scroll;
case DOM_VK_WIN_OEM_FJ_JISHO:
case DOM_VK_WIN_OEM_FJ_MASSHOU:
case DOM_VK_WIN_OEM_FJ_TOUROKU:
case DOM_VK_WIN_OEM_FJ_LOYA:
case DOM_VK_WIN_OEM_FJ_ROYA:
case DOM_VK_CIRCUMFLEX:
return Aspect_VKey_UNKNOWN;
case DOM_VK_EXCLAMATION:
case DOM_VK_DOUBLE_QUOTE:
//case DOM_VK_HASH:
case DOM_VK_DOLLAR:
case DOM_VK_PERCENT:
case DOM_VK_AMPERSAND:
case DOM_VK_UNDERSCORE:
case DOM_VK_OPEN_PAREN:
case DOM_VK_CLOSE_PAREN:
case DOM_VK_ASTERISK:
return Aspect_VKey_UNKNOWN;
case DOM_VK_PLUS:
return Aspect_VKey_Plus;
case DOM_VK_PIPE:
case DOM_VK_HYPHEN_MINUS:
return Aspect_VKey_UNKNOWN;
case DOM_VK_OPEN_CURLY_BRACKET:
return Aspect_VKey_BracketLeft;
case DOM_VK_CLOSE_CURLY_BRACKET:
return Aspect_VKey_BracketRight;
case DOM_VK_TILDE:
return Aspect_VKey_Tilde;
case DOM_VK_VOLUME_MUTE:
return Aspect_VKey_VolumeMute;
case DOM_VK_VOLUME_DOWN:
return Aspect_VKey_VolumeDown;
case DOM_VK_VOLUME_UP:
return Aspect_VKey_VolumeUp;
case DOM_VK_COMMA:
return Aspect_VKey_Comma;
case DOM_VK_PERIOD:
return Aspect_VKey_Period;
case DOM_VK_SLASH:
return Aspect_VKey_Slash;
case DOM_VK_BACK_QUOTE:
return Aspect_VKey_UNKNOWN;
case DOM_VK_OPEN_BRACKET:
return Aspect_VKey_BracketLeft;
case DOM_VK_BACK_SLASH:
return Aspect_VKey_Backslash;
case DOM_VK_CLOSE_BRACKET:
return Aspect_VKey_BracketRight;
case DOM_VK_QUOTE:
return Aspect_VKey_UNKNOWN;
case DOM_VK_META:
return Aspect_VKey_Meta;
case DOM_VK_ALTGR:
return Aspect_VKey_Alt;
case DOM_VK_WIN_ICO_HELP:
case DOM_VK_WIN_ICO_00:
case DOM_VK_WIN_ICO_CLEAR:
case DOM_VK_WIN_OEM_RESET:
case DOM_VK_WIN_OEM_JUMP:
case DOM_VK_WIN_OEM_PA1:
case DOM_VK_WIN_OEM_PA2:
case DOM_VK_WIN_OEM_PA3:
case DOM_VK_WIN_OEM_WSCTRL:
case DOM_VK_WIN_OEM_CUSEL:
case DOM_VK_WIN_OEM_ATTN:
case DOM_VK_WIN_OEM_FINISH:
case DOM_VK_WIN_OEM_COPY:
case DOM_VK_WIN_OEM_AUTO:
case DOM_VK_WIN_OEM_ENLW:
case DOM_VK_WIN_OEM_BACKTAB:
case DOM_VK_ATTN:
case DOM_VK_CRSEL:
case DOM_VK_EXSEL:
case DOM_VK_EREOF:
return Aspect_VKey_UNKNOWN;
case DOM_VK_PLAY:
return Aspect_VKey_MediaPlayPause;
case DOM_VK_ZOOM:
case DOM_VK_PA1:
case DOM_VK_WIN_OEM_CLEAR:
return Aspect_VKey_UNKNOWN;
}
return Aspect_VKey_UNKNOWN;
}
#endif // _WasmVKeys_HeaderFile

66
samples/webgl/main.cpp Normal file
View File

@@ -0,0 +1,66 @@
#include <iostream>
#include "WasmOcctView.h"
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <OSD_MemInfo.hxx>
#include <OSD_Parallel.hxx>
#include <AIS_Shape.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Standard_ArrayStreamBuffer.hxx>
#include <emscripten.h>
#include <emscripten/html5.h>
//! Global viewer instance.
static WasmOcctView aViewer;
//! File data read event.
extern "C" void onFileDataRead (void* theOpaque, void* theBuffer, int theDataLen)
{
const char* aName = theOpaque != NULL ? (const char* )theOpaque : "";
{
AIS_ListOfInteractive aShapes;
aViewer.Context()->DisplayedObjects (AIS_KOI_Shape, -1, aShapes);
for (AIS_ListOfInteractive::Iterator aShapeIter (aShapes); aShapeIter.More(); aShapeIter.Next())
{
aViewer.Context()->Remove (aShapeIter.Value(), false);
}
}
Standard_ArrayStreamBuffer aStreamBuffer ((const char* )theBuffer, theDataLen);
std::istream aStream (&aStreamBuffer);
TopoDS_Shape aShape;
BRep_Builder aBuilder;
BRepTools::Read (aShape, aStream, aBuilder);
Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape);
aShapePrs->SetMaterial (Graphic3d_NOM_SILVER);
aViewer.Context()->Display (aShapePrs, AIS_Shaded, 0, false);
aViewer.View()->FitAll (0.01, false);
aViewer.View()->Redraw();
Message::DefaultMessenger()->Send (TCollection_AsciiString("Loaded file ") + aName, Message_Info);
Message::DefaultMessenger()->Send (OSD_MemInfo::PrintInfo(), Message_Trace);
}
//! File read error event.
static void onFileReadFailed (void* theOpaque)
{
const char* aName = (const char* )theOpaque;
Message::DefaultMessenger()->Send (TCollection_AsciiString("Error: unable to load file ") + aName, Message_Fail);
}
int main()
{
Message::DefaultMessenger()->Printers().First()->SetTraceLevel (Message_Trace);
Message::DefaultMessenger()->Send (TCollection_AsciiString("NbLogicalProcessors: ") + OSD_Parallel::NbLogicalProcessors(), Message_Trace);
aViewer.run();
Message::DefaultMessenger()->Send (OSD_MemInfo::PrintInfo(), Message_Trace);
// load some file
emscripten_async_wget_data ("samples/Ball.brep", (void* )"samples/Ball.brep", onFileDataRead, onFileReadFailed);
return 0;
}

View File

@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang=en-us>
<head>
<meta charset=utf-8><meta content="text/html; charset=utf-8" http-equiv=Content-Type>
<link rel="shortcut icon" href="lamp.ico" type="image/x-icon" />
<title>OCCT WebGL Viewer Sample</title>
</head>
<body>
<h2>OCCT WebGL Viewer Sample</h2>
<div>
<canvas id=canvas oncontextmenu=event.preventDefault() tabindex=-1 style="border:0 none;background-color:#000" width="409" height="409"></canvas>
<img id=occlogo src="OCC_logo.png" style="position: absolute; left: 20px; top: 0px; z-index: 2;" />
</div>
<div><label for="fileInput">Choose BREP file to upload: </label><input type="file" id="fileInput" accept=".brep"></div>
<h4>Console output:</h4>
<p id="output"></p>
<script>
//! Resize canvas to fit into window.
function updateCanvasSize()
{
// size of canvas in logical (density-independent) units
var aSizeX = Math.min (window.innerWidth, window.screen.availWidth);
var aSizeY = Math.min (window.innerHeight, window.screen.availHeight);
aSizeX = Math.max (300, aSizeX - 30);
aSizeY = Math.max (300, aSizeY / 2);
canvas.style.width = aSizeX + "px";
canvas.style.height = aSizeY + "px";
// drawing buffer size (aka backing store)
var aDevicePixelRatio = window.devicePixelRatio || 1;
canvas.width = aSizeX * aDevicePixelRatio;
canvas.height = aSizeY * aDevicePixelRatio;
occlogo.style.top = (aSizeY - 30) + "px";
}
window.onresize = updateCanvasSize;
updateCanvasSize();
//! Check browser support.
function isWasmSupported()
{
try {
if (typeof WebAssembly === "object"
&& typeof WebAssembly.instantiate === "function") {
const aDummyModule = new WebAssembly.Module (Uint8Array.of (0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
if (aDummyModule instanceof WebAssembly.Module)
{
return new WebAssembly.Instance(aDummyModule) instanceof WebAssembly.Instance;
}
}
} catch (e) {}
return false;
}
if (!isWasmSupported())
{
var anElement = document.getElementById('output');
anElement.innerHTML += "Browser is too old - WebAssembly support is missing!<br>Please check updates or install a modern browser.<br>";
}
//! Define OCCT WebGL Viewer module.
var Module =
{
print: (function() {
var anElement = document.getElementById('output');
return function(theText) { anElement.innerHTML += theText + "<br>"; };
})(),
printErr: function(theText) {
//var anElement = document.getElementById('output');
//anElement.innerHTML += theText + "<br>";
},
canvas: (function() {
var aCanvas = document.getElementById('canvas');
return aCanvas;
})()
};
//! Handle file uploading.
fileInput.onchange = function()
{
if (fileInput.files.length == 0) { return; }
// Warning! Entire file is pre-loaded into memory.
var aFile = fileInput.files[0];
var aReader = new FileReader();
aReader.onload = function()
{
var aDataArray = new Uint8Array (aReader.result);
var aNameArray = new Uint8Array (toUtf8Array (aFile.name));
const aDataBuffer = Module._malloc(aDataArray.length);
const aNameBuffer = Module._malloc(aNameArray.length);
Module.HEAPU8.set(aNameArray, aNameBuffer);
Module.HEAPU8.set(aDataArray, aDataBuffer);
Module.ccall('onFileDataRead', null, ['number', 'number', 'number'], [aNameBuffer, aDataBuffer, aDataArray.length]);
Module._free(aDataBuffer);
Module._free(aNameBuffer);
fileInput.value = '';
};
aReader.readAsArrayBuffer(aFile);
};
//! Convert string into UTF-8 array.
function toUtf8Array (theText)
{
var aRes = [];
for (var aCharIter = 0; aCharIter < theText.length; ++aCharIter)
{
var aCharCode = theText.charCodeAt (aCharIter);
if (aCharCode < 0x80)
{
aRes.push (aCharCode);
}
else if (aCharCode < 0x800)
{
aRes.push (0xc0 | (aCharCode >> 6), 0x80 | (aCharCode & 0x3f));
}
else if (aCharCode < 0xd800 || aCharCode >= 0xe000)
{
aRes.push (0xe0 | (aCharCode >> 12), 0x80 | ((aCharCode>>6) & 0x3f), 0x80 | (aCharCode & 0x3f));
}
else
{
++aCharIter;
aCharCode = 0x10000 + (((aCharCode & 0x3ff)<<10) | (theText.charCodeAt (aCharIter) & 0x3ff));
aRes.push(0xf0 | (aCharCode >>18), 0x80 | ((aCharCode>>12) & 0x3f), 0x80 | ((aCharCode>>6) & 0x3f), 0x80 | (aCharCode & 0x3f));
}
}
return aRes;
}
</script>
<script type="text/javascript" src="occt-webgl-sample.js" charset="utf-8"></script>
</body>
</html>

View File

@@ -415,11 +415,6 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
//=======================================================================
Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const
{
{
Handle(V3d_Viewer) aViewer = GetContext()->CurrentViewer();
aViewer->InitActiveViews(); // for AIS_ColorScale::TextSize()
}
Standard_Integer aWidthMax = 0;
for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next())
{

View File

@@ -26,6 +26,7 @@ public:
//! Default constructor.
AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink)
: myIsHidden (false),
myHasOwnMaterial(false),
myHasOwnColor (false),
myHasOwnTransp(false),
myHasOwnWidth (false)
@@ -36,6 +37,10 @@ public:
bool IsHidden() const { return myIsHidden; }
void SetHidden (const bool theToHide) { myIsHidden = theToHide;}
bool HasOwnMaterial() const { return myHasOwnMaterial; }
void UnsetOwnMaterial() { myHasOwnMaterial = false; }
void SetOwnMaterial() { myHasOwnMaterial = true; }
bool HasOwnColor() const { return myHasOwnColor; }
void UnsetOwnColor() { myHasOwnColor = false; }
void SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = true; }
@@ -51,6 +56,7 @@ public:
public: //! @name list of overridden properties
bool myIsHidden;
bool myHasOwnMaterial;
bool myHasOwnColor;
bool myHasOwnTransp;
bool myHasOwnWidth;

View File

@@ -333,7 +333,11 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
{
const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
//if (aDrawer->HasOwnMaterial()) continue;
if (aDrawer->HasOwnMaterial())
{
continue;
}
if (aDrawer->HasOwnShadingAspect())
{
setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), aDrawer->HasOwnTransparency());

View File

@@ -79,6 +79,12 @@ void AIS_ConnectedInteractive::connect (const Handle(AIS_InteractiveObject)& the
if (!myReference.IsNull())
{
if (myReference->HasInteractiveContext()
&& myReference->GetContext()->DisplayStatus (myReference) != AIS_DS_None)
{
myReference.Nullify();
throw Standard_ProgramError("AIS_ConnectedInteractive::Connect() - connected object should NOT be displayed in context");
}
myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
}
setLocalTransformation (theLocation);

View File

@@ -65,15 +65,13 @@ namespace
typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)>::Iterator AIS_MapIteratorOfMapOfObjectOwners;
//! Initialize default highlighting attributes.
static void initDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer,
const Quantity_Color& theColor)
static void initDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
{
theDrawer->SetMethod (Aspect_TOHM_COLOR);
theDrawer->SetDisplayMode (0);
theDrawer->SetColor (theColor);
theDrawer->SetupOwnShadingAspect();
theDrawer->SetupOwnPointAspect();
theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
*theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
*theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
@@ -84,24 +82,6 @@ namespace
*theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
*theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
theDrawer->SetDatumAspect (new Prs3d_DatumAspect());
theDrawer->ShadingAspect()->SetColor (theColor);
theDrawer->WireAspect()->SetColor (theColor);
theDrawer->LineAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->ArrowAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->IsoAspect()->SetColor (theColor);
theDrawer->PlaneAspect()->EdgesAspect()->SetColor (theColor);
theDrawer->FreeBoundaryAspect()->SetColor (theColor);
theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
theDrawer->PointAspect()->SetColor (theColor);
for (Standard_Integer aPartIter = 0; aPartIter < Prs3d_DP_None; ++aPartIter)
{
if (Handle(Prs3d_LineAspect) aLineAsp = theDrawer->DatumAspect()->LineAspect ((Prs3d_DatumParts )aPartIter))
{
aLineAsp->SetColor (theColor);
}
}
theDrawer->WireAspect()->SetWidth (2.0);
theDrawer->LineAspect()->SetWidth (2.0);
@@ -150,26 +130,30 @@ myIsAutoActivateSelMode(Standard_True)
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Dynamic];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
initDefaultHilightAttributes (aStyle);
aStyle->SetZLayer(Graphic3d_ZLayerId_Top);
aStyle->SetColor (Quantity_NOC_CYAN1);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalDynamic];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
initDefaultHilightAttributes (aStyle);
aStyle->SetZLayer(Graphic3d_ZLayerId_Topmost);
aStyle->SetColor (Quantity_NOC_CYAN1);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Selected];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
initDefaultHilightAttributes (aStyle);
aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
aStyle->SetColor (Quantity_NOC_GRAY80);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalSelected];
aStyle->Link (myDefaultDrawer);
initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
initDefaultHilightAttributes (aStyle);
aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
aStyle->SetColor (Quantity_NOC_GRAY80);
}
{
const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];

View File

@@ -44,8 +44,7 @@ AIS_TextLabel::AIS_TextLabel()
myHasFlipping (Standard_False)
{
myDrawer->SetTextAspect (new Prs3d_TextAspect());
SetDisplayMode (0);
myDrawer->SetDisplayMode (0);
}
//=======================================================================

View File

@@ -32,6 +32,9 @@ public:
//! Default constructor
Standard_EXPORT AIS_TextLabel();
//! Return TRUE for supported display mode.
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
//! Setup color of entire text.
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;

View File

@@ -32,7 +32,6 @@
#include <Prs3d_DatumAspect.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_PointAspect.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_Projector.hxx>
#include <Prs3d_ShadingAspect.hxx>
@@ -60,8 +59,6 @@ AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
myTrihDispMode (Prs3d_DM_WireFrame),
myComponent (theComponent)
{
myAutoHilight = Standard_False;
// selection priorities
mySelectionPriority.Bind (Prs3d_DP_None, 5); // complete triedron: priority 5 (same as faces)
mySelectionPriority.Bind (Prs3d_DP_Origin, 8); // origin: priority 8
@@ -73,7 +70,6 @@ AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
{
mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 5); // planes: priority: 5
}
myHiddenLineAspect = new Graphic3d_AspectLine3d (Quantity_NOC_WHITE, Aspect_TOL_EMPTY, 1.0f);
// trihedron labels
myLabel.Bind (Prs3d_DP_XAxis, "X");
@@ -139,6 +135,7 @@ void AIS_Trihedron::SetSize(const Standard_Real aValue)
myDrawer->DatumAspect()->SetAxisLength(aValue, aValue, aValue);
SetToUpdate();
UpdatePresentations();
UpdateSelection();
}
@@ -166,6 +163,7 @@ void AIS_Trihedron::UnsetSize()
else
{
SetToUpdate();
UpdatePresentations();
}
UpdateSelection();
}
@@ -312,37 +310,36 @@ void AIS_Trihedron::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManag
aPresentation->Clear();
const Prs3d_DatumParts aPart = anOwner->DatumPart();
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
if (aPart >= Prs3d_DP_XOYAxis && aPart <= Prs3d_DP_XOZAxis)
{
// planes selection is equal in both shading and wireframe mode
aGroup->SetGroupPrimitivesAspect (theStyle->LineAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
}
else
{
if (myTrihDispMode == Prs3d_DM_Shaded)
{
aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect(aPart)->Aspect());
}
else
{
if (aPart == Prs3d_DP_Origin)
{
aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
}
else
{
aGroup->SetGroupPrimitivesAspect(theStyle->LineAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect(aPart)->Aspect());
}
}
}
aGroup->AddPrimitiveArray (arrayOfPrimitives(aPart));
const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
if (aPresentation->GetZLayer() != aLayer)
if (aPresentation->GetZLayer() != theStyle->ZLayer())
{
aPresentation->SetZLayer (aLayer);
aPresentation->SetZLayer (theStyle->ZLayer());
}
aPresentation->Highlight (theStyle);
thePM->AddToImmediateList (aPresentation);
}
@@ -359,22 +356,25 @@ void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)&
return;
}
Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
Handle(Prs3d_Drawer) anAspect = !myHilightDrawer.IsNull() ? myHilightDrawer : GetContext()->SelectionStyle();
const Handle(Prs3d_Drawer)& aContextSelStyle = GetContext()->SelectionStyle();
const Quantity_Color& aSelectionColor = aContextSelStyle->Color();
for (SelectMgr_SequenceOfOwner::Iterator anIterator (theOwners); anIterator.More(); anIterator.Next())
{
const Handle(SelectMgr_EntityOwner)& anOwner = anIterator.Value();
Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(anOwner);
if (aTrihedronOwner.IsNull())
{
thePM->Color (this, anAspect, 0);
thePM->Color (this, aContextSelStyle, 0);
continue;
}
const Prs3d_DatumParts aPart = aTrihedronOwner->DatumPart();
Handle(Graphic3d_Group) aGroup;
if (mySelectedParts.Contains (aPart) || !myPartToGroup.Find (aPart, aGroup))
if (mySelectedParts.Contains (aPart)
|| !myPartToGroup.Find (aPart, aGroup))
{
continue;
}
@@ -382,23 +382,27 @@ void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)&
if (aPart >= Prs3d_DP_XOYAxis
&& aPart <= Prs3d_DP_XOZAxis)
{
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
getHighlightLineAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
}
else
{
if (isShadingMode)
{
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect()->Aspect());
getHighlightAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightAspect()->Aspect());
}
else
{
if (aPart == Prs3d_DP_Origin)
{
aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
getHighlightPointAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
}
else
{
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
getHighlightLineAspect()->SetColor (aSelectionColor);
aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
}
}
}
@@ -422,9 +426,9 @@ void AIS_Trihedron::ClearSelected()
if (aPart >= Prs3d_DP_XOYAxis
&& aPart <= Prs3d_DP_XOZAxis)
{
aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
}
else if (isShadingMode)
if (isShadingMode)
{
aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
}
@@ -549,8 +553,11 @@ void AIS_Trihedron::computePresentation (const Handle(PrsMgr_PresentationManager
Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
myPartToGroup.Bind (aPart, aGroup);
const Handle(Graphic3d_AspectLine3d)& aLineAspect = anAspect->LineAspect (aPart)->Aspect();
aLineAspect->SetType (Aspect_TOL_EMPTY);
aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
aGroup->SetGroupPrimitivesAspect (aLineAspect);
}
}
@@ -926,3 +933,65 @@ void AIS_Trihedron::updatePrimitives(const Handle(Prs3d_DatumAspect)& theAspect,
myPrimitives.Bind(aPart, aPrims);
}
}
// =======================================================================
// function : getHighlightAspect
// purpose :
// =======================================================================
Handle(Prs3d_ShadingAspect) AIS_Trihedron::getHighlightAspect()
{
if (!myHighlightAspect.IsNull())
return myHighlightAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
myHighlightAspect = new Prs3d_ShadingAspect();
myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
myHighlightAspect->SetColor (aHighlightColor);
Graphic3d_MaterialAspect aHighlightMaterial;
aHighlightMaterial.SetColor (aHighlightColor);
myHighlightAspect->SetMaterial (aHighlightMaterial);
return myHighlightAspect;
}
// =======================================================================
// function : getHighlightLineAspect
// purpose :
// =======================================================================
Handle(Prs3d_LineAspect) AIS_Trihedron::getHighlightLineAspect()
{
if (!myHighlightLineAspect.IsNull())
return myHighlightLineAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
Handle(Prs3d_DatumAspect) aDatumAspect = Attributes()->DatumAspect();
Handle(Prs3d_LineAspect) aLineAspect = aDatumAspect->LineAspect(Prs3d_DP_XAxis);
myHighlightLineAspect = new Prs3d_LineAspect (aHighlightColor, aLineAspect->Aspect()->Type(),
aLineAspect->Aspect()->Width());
return myHighlightLineAspect;
}
// =======================================================================
// function : getHighlightPointAspect
// purpose :
// =======================================================================
Handle(Prs3d_PointAspect) AIS_Trihedron::getHighlightPointAspect()
{
if (!myHighlightPointAspect.IsNull())
return myHighlightPointAspect;
Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
if (!myHilightDrawer.IsNull())
aHighlightColor = myHilightDrawer->Color();
myHighlightPointAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, aHighlightColor, 1.0);
return myHighlightPointAspect;
}

View File

@@ -186,6 +186,9 @@ public:
public:
//! Disables auto highlighting to use HilightSelected() and HilightOwnerWithColor() overridden methods.
virtual Standard_Boolean IsAutoHilight() const Standard_OVERRIDE { return false; }
//! Method which clear all selected owners belonging
//! to this selectable object ( for fast presentation draw ).
Standard_EXPORT virtual void ClearSelected() Standard_OVERRIDE;
@@ -245,6 +248,13 @@ protected:
const gp_Dir& theYDir,
const gp_Dir& theZDir);
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_ShadingAspect) getHighlightAspect();
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_LineAspect) getHighlightLineAspect();
//! Returns highlight line aspect , create if it is the first call
Handle(Prs3d_PointAspect) getHighlightPointAspect();
protected:
Standard_Boolean myHasOwnSize;
Standard_Boolean myHasOwnTextColor;
@@ -259,7 +269,10 @@ protected:
NCollection_DataMap<Prs3d_DatumParts, Handle(Graphic3d_Group)> myPartToGroup;
NCollection_List<Prs3d_DatumParts> mySelectedParts;
Handle(Graphic3d_AspectLine3d) myHiddenLineAspect;
Handle(Prs3d_ShadingAspect) myHighlightAspect;
Handle(Prs3d_LineAspect) myHighlightLineAspect;
Handle(Prs3d_PointAspect) myHighlightPointAspect;
NCollection_DataMap<Prs3d_DatumParts, Handle(Graphic3d_ArrayOfPrimitives)> myPrimitives;
};

View File

@@ -69,6 +69,7 @@ AIS_ViewController::AIS_ViewController()
myMousePressed (Aspect_VKeyMouse_NONE),
myMouseModifiers (Aspect_VKeyFlags_NONE),
myMouseSingleButton (-1),
myMouseStopDragOnUnclick (false),
//
myTouchToleranceScale (1.0f),
myTouchRotationThresholdPx (6.0f),
@@ -611,6 +612,7 @@ bool AIS_ViewController::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
{
myMouseClickTimer.Stop();
myMouseClickCounter = 0;
myMouseStopDragOnUnclick = false;
myUI.Dragging.ToStop = true;
toUpdateView = true;
}
@@ -619,6 +621,12 @@ bool AIS_ViewController::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
else if (theButtons == Aspect_VKeyMouse_NONE)
{
myMouseSingleButton = -1;
if (myMouseStopDragOnUnclick)
{
myMouseStopDragOnUnclick = false;
myUI.Dragging.ToStop = true;
toUpdateView = true;
}
}
else if (myMouseSingleButton == -1)
{
@@ -769,6 +777,7 @@ bool AIS_ViewController::UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
myMouseClickTimer.Stop();
myMouseClickCounter = 0;
myMouseSingleButton = -1;
myMouseStopDragOnUnclick = true;
}
}
@@ -2192,6 +2201,7 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
aPolyIter.ChangeValue() = gp_Pnt2d (aNewPnt.x(), -aNewPnt.y());
}
theCtx->MainSelector()->AllowOverlapDetection (false);
if (myGL.Selection.IsXOR)
{
theCtx->ShiftSelect (aPolyline, theView, false);
@@ -2200,7 +2210,6 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
{
theCtx->Select (aPolyline, theView, false);
}
theCtx->MainSelector()->AllowOverlapDetection (false);
}
}

View File

@@ -647,6 +647,7 @@ protected: //! @name mouse input variables
Aspect_VKeyMouse myMousePressed; //!< active mouse buttons
Aspect_VKeyFlags myMouseModifiers; //!< active key modifiers passed with last mouse event
Standard_Integer myMouseSingleButton; //!< index of mouse button pressed alone (>0)
Standard_Boolean myMouseStopDragOnUnclick; //!< queue stop dragging even with at next mouse unclick
protected: //! @name multi-touch input variables

View File

@@ -137,6 +137,9 @@ AIS_ViewCube::AIS_ViewCube()
myBoxEdgeGap (0.0),
myBoxFacetExtension (1.0),
myAxesPadding (1.0),
myAxesRadius (1.0),
myAxesConeRadius (3.0),
myAxesSphereRadius (4.0),
myCornerMinSize (2.0),
myRoundRadius (0.0),
myToDisplayAxes (true),
@@ -599,7 +602,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
anAxisGroup->SetGroupPrimitivesAspect (aDatumAspect->ShadingAspect (aPart)->Aspect());
const Standard_Real anArrowLength = 0.2 * anAxisSize;
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, 1.0, anAxisSize, 3.0, anArrowLength, THE_NB_ARROW_FACETTES);
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, myAxesRadius, anAxisSize, myAxesConeRadius, anArrowLength, THE_NB_ARROW_FACETTES);
anAxisGroup->AddPrimitiveArray (aTriangleArray);
TCollection_AsciiString anAxisLabel;
@@ -621,7 +624,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect();
anAspectCen->SetColor (Quantity_NOC_WHITE);
aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
Prs3d_ToolSphere aTool (4.0, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
Prs3d_ToolSphere aTool (myAxesSphereRadius, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
gp_Trsf aTrsf;
aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
Handle(Graphic3d_ArrayOfTriangles) aCenterArray;

View File

@@ -189,6 +189,45 @@ public: //! @name Geometry management API
//! The value should be within [0, 0.5] range.
Standard_EXPORT void SetRoundRadius (const Standard_Real theValue);
//! Returns radius of axes of the trihedron; 1.0 by default.
Standard_Real AxesRadius() const { return myAxesRadius; }
//! Sets radius of axes of the trihedron.
void SetAxesRadius (const Standard_Real theRadius)
{
if (Abs (myAxesRadius - theRadius) > Precision::Confusion())
{
myAxesRadius = theRadius;
SetToUpdate();
}
}
//! Returns radius of cone of axes of the trihedron; 3.0 by default.
Standard_Real AxesConeRadius() const { return myAxesConeRadius; }
//! Sets radius of cone of axes of the trihedron.
void SetAxesConeRadius (Standard_Real theRadius)
{
if (Abs (myAxesConeRadius - theRadius) > Precision::Confusion())
{
myAxesConeRadius = theRadius;
SetToUpdate();
}
}
//! Returns radius of sphere (central point) of the trihedron; 4.0 by default.
Standard_Real AxesSphereRadius() const { return myAxesSphereRadius; }
//! Sets radius of sphere (central point) of the trihedron.
void SetAxesSphereRadius (Standard_Real theRadius)
{
if (Abs (myAxesSphereRadius - theRadius) > Precision::Confusion())
{
myAxesSphereRadius = theRadius;
SetToUpdate();
}
}
//! @return TRUE if trihedron is drawn; TRUE by default.
Standard_Boolean ToDrawAxes() const { return myToDisplayAxes; }
@@ -621,6 +660,9 @@ protected:
Standard_Real myBoxEdgeGap; //!< gap between box side and box edge
Standard_Real myBoxFacetExtension; //!< box facet extension
Standard_Real myAxesPadding; //!< Padding between box and axes
Standard_Real myAxesRadius; //!< radius of axes of the trihedron; 1.0 by default
Standard_Real myAxesConeRadius; //!< radius of cone of axes of the trihedron; 3.0 by default
Standard_Real myAxesSphereRadius; //!< radius of sphere (central point) of the trihedron; 4.0 by default
Standard_Real myCornerMinSize; //!< minimal size of box corner
Standard_Real myRoundRadius; //!< relative round radius within [0; 0.5] range
Standard_Boolean myToDisplayAxes; //!< trihedron visibility

View File

@@ -54,7 +54,6 @@ const AppParCurves_Constraint LastC)
mylastC = LastC;
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
myHangChecking = Standard_True;
alldone = Standard_False;
Perform(Line);
}
@@ -83,7 +82,6 @@ const AppParCurves_Constraint LastC)
mylastC = LastC;
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
myHangChecking = Standard_True;
}
//=======================================================================
@@ -99,20 +97,12 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
Standard_Real thetol3d = Precision::Confusion(), thetol2d = Precision::Confusion();
UFirst = Line.FirstParameter();
ULast = Line.LastParameter();
Standard_Real TolU = 0.;
if (myHangChecking)
{
TolU = Max((ULast - UFirst)*1.e-03, Precision::Confusion());
}
else
{
TolU = Max((ULast - UFirst)*1.e-05, Precision::PApproximation());
}
Standard_Real TolU = Max((ULast - UFirst)*1.e-03, Precision::Confusion());
Standard_Real myfirstU = UFirst;
Standard_Real mylastU = ULast;
Standard_Integer aMaxSegments = 0;
Standard_Integer aMaxSegments1 = myMaxSegments - 1;
Standard_Integer aNbCut = 0, aNbImp = 0, aNbComp = 10;
Standard_Integer aNbCut = 0, aNbImp = 0, aNbComp = 5;
if (!mycut)
{
@@ -186,14 +176,12 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
//cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
Standard_Boolean aStopCutting = Standard_False;
if (myHangChecking && aNbCut >= aNbComp)
if (aNbCut >= aNbComp)
{
if (aNbCut > aNbImp + 1)
if (aNbCut > aNbImp)
{
aStopCutting = Standard_True;
}
aNbCut = 0;
aNbImp = 0;
}
// is new decision better?
if (!Ok && (Abs(myfirstU - mylastU) <= TolU || aMaxSegments >= aMaxSegments1 || aStopCutting ))
@@ -444,15 +432,6 @@ void Approx_ComputeCLine::SetInvOrder(const Standard_Boolean theInvOrder)
myInvOrder = theInvOrder;
}
//=======================================================================
//function : SetHangChecking
//purpose :
//=======================================================================
void Approx_ComputeCLine::SetHangChecking(const Standard_Boolean theHangChecking)
{
myHangChecking = theHangChecking;
}
//=======================================================================
//function : IsAllApproximated
//purpose : returns False if at a moment of the approximation,

View File

@@ -27,8 +27,10 @@
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomConvert.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
@@ -300,6 +302,10 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
}
}
//=============================================================================
//function : Approx_CurveOnSurface
//purpose : Constructor
//=============================================================================
Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D,
const Handle(Adaptor3d_HSurface)& Surf,
const Standard_Real First,
@@ -310,14 +316,75 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
const Standard_Integer MaxSegments,
const Standard_Boolean only3d,
const Standard_Boolean only2d)
: myC2D(C2D),
mySurf(Surf),
myFirst(First),
myLast(Last),
myTol(Tol),
myIsDone(Standard_False),
myHasResult(Standard_False),
myError3d(0.0),
myError2dU(0.0),
myError2dV(0.0)
{
Perform(MaxSegments, MaxDegree, S, only3d, only2d);
}
//=============================================================================
//function : Approx_CurveOnSurface
//purpose : Constructor
//=============================================================================
Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Real theFirst,
const Standard_Real theLast,
const Standard_Real theTol)
: myC2D(theC2D),
mySurf(theSurf),
myFirst(theFirst),
myLast(theLast),
myTol(theTol),
myIsDone(Standard_False),
myHasResult(Standard_False),
myError3d(0.0),
myError2dU(0.0),
myError2dV(0.0)
{
}
//=============================================================================
//function : Perform
//purpose :
//=============================================================================
void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
const Standard_Integer theMaxDegree,
const GeomAbs_Shape theContinuity,
const Standard_Boolean theOnly3d,
const Standard_Boolean theOnly2d)
{
myIsDone = Standard_False;
if(only3d && only2d) throw Standard_ConstructionError();
GeomAbs_Shape Order = S;
myHasResult = Standard_False;
myError2dU = 0.0;
myError2dV = 0.0;
myError3d = 0.0;
Handle( Adaptor2d_HCurve2d ) TrimmedC2D = C2D->Trim( First, Last, Precision::PConfusion() );
if(theOnly3d && theOnly2d) throw Standard_ConstructionError();
Adaptor3d_CurveOnSurface COnS( TrimmedC2D, Surf );
Handle( Adaptor2d_HCurve2d ) TrimmedC2D = myC2D->Trim( myFirst, myLast, Precision::PConfusion() );
Standard_Boolean isU, isForward;
Standard_Real aParam;
if (theOnly3d && isIsoLine(TrimmedC2D, isU, aParam, isForward))
{
if (buildC3dOnIsoLine(TrimmedC2D, isU, aParam, isForward))
{
myIsDone = Standard_True;
myHasResult = Standard_True;
return;
}
}
Adaptor3d_CurveOnSurface COnS( TrimmedC2D, mySurf );
Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface();
HCOnS->Set(COnS);
@@ -327,37 +394,34 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
Handle(TColStd_HArray1OfReal) ThreeDTol;
// create evaluators and choose appropriate one
Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS, First, Last);
Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf ( TrimmedC2D, First, Last);
Approx_CurveOnSurface_Eval EvalCvOnSurf (HCOnS, TrimmedC2D, First, Last);
Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS, myFirst, myLast);
Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf ( TrimmedC2D, myFirst, myLast);
Approx_CurveOnSurface_Eval EvalCvOnSurf (HCOnS, TrimmedC2D, myFirst, myLast);
AdvApprox_EvaluatorFunction* EvalPtr;
if ( only3d ) EvalPtr = &Eval3dCvOnSurf;
else if ( only2d ) EvalPtr = &Eval2dCvOnSurf;
if ( theOnly3d ) EvalPtr = &Eval3dCvOnSurf;
else if ( theOnly2d ) EvalPtr = &Eval2dCvOnSurf;
else EvalPtr = &EvalCvOnSurf;
// Initialization for 2d approximation
if(!only3d) {
if(!theOnly3d) {
Num1DSS = 2;
OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
Standard_Real TolU, TolV;
TolU = Surf->UResolution(Tol)/2;
TolV = Surf->VResolution(Tol)/2;
TolU = mySurf->UResolution(myTol)/2;
TolV = mySurf->VResolution(myTol)/2;
OneDTol->SetValue(1,TolU);
OneDTol->SetValue(2,TolV);
}
if(!only2d) {
if(!theOnly2d) {
Num3DSS=1;
ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol/2);
ThreeDTol->Init(myTol/2);
}
myError2dU = 0;
myError2dV = 0;
myError3d = 0;
Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
@@ -369,8 +433,8 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTol, TwoDTolNul, ThreeDTol,
First, Last, Order,
MaxDegree, MaxSegments,
myFirst, myLast, theContinuity,
theMaxDegree, theMaxSegments,
*EvalPtr, CutTool);
myIsDone = aApprox.IsDone();
@@ -381,14 +445,14 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
if(!only2d)
if(!theOnly2d)
{
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
aApprox.Poles(1,Poles);
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
myError3d = aApprox.MaxError(3, 1);
}
if(!only3d)
if(!theOnly3d)
{
TColgp_Array1OfPnt2d Poles2d(1,aApprox.NbPoles());
TColStd_Array1OfReal Poles1dU(1,aApprox.NbPoles());
@@ -404,8 +468,6 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
}
}
// }
}
Standard_Boolean Approx_CurveOnSurface::IsDone() const
@@ -443,3 +505,161 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
return myError2dV;
}
//=============================================================================
//function : isIsoLine
//purpose :
//=============================================================================
Standard_Boolean Approx_CurveOnSurface::isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
Standard_Boolean& theIsU,
Standard_Real& theParam,
Standard_Boolean& theIsForward) const
{
// These variables are used to check line state (vertical or horizontal).
Standard_Boolean isAppropriateType = Standard_False;
gp_Pnt2d aLoc2d;
gp_Dir2d aDir2d;
// Test type.
const GeomAbs_CurveType aType = theC2D->GetType();
if (aType == GeomAbs_Line)
{
gp_Lin2d aLin2d = theC2D->Line();
aLoc2d = aLin2d.Location();
aDir2d = aLin2d.Direction();
isAppropriateType = Standard_True;
}
else if (aType == GeomAbs_BSplineCurve)
{
Handle(Geom2d_BSplineCurve) aBSpline2d = theC2D->BSpline();
if (aBSpline2d->Degree() != 1 || aBSpline2d->NbPoles() != 2)
return Standard_False; // Not a line or uneven parameterization.
aLoc2d = aBSpline2d->Pole(1);
// Vector should be non-degenerated.
gp_Vec2d aVec2d(aBSpline2d->Pole(1), aBSpline2d->Pole(2));
if (aVec2d.SquareMagnitude() < Precision::Confusion())
return Standard_False; // Degenerated spline.
aDir2d = aVec2d;
isAppropriateType = Standard_True;
}
else if (aType == GeomAbs_BezierCurve)
{
Handle(Geom2d_BezierCurve) aBezier2d = theC2D->Bezier();
if (aBezier2d->Degree() != 1 || aBezier2d->NbPoles() != 2)
return Standard_False; // Not a line or uneven parameterization.
aLoc2d = aBezier2d->Pole(1);
// Vector should be non-degenerated.
gp_Vec2d aVec2d(aBezier2d->Pole(1), aBezier2d->Pole(2));
if (aVec2d.SquareMagnitude() < Precision::Confusion())
return Standard_False; // Degenerated spline.
aDir2d = aVec2d;
isAppropriateType = Standard_True;
}
if (!isAppropriateType)
return Standard_False;
// Check line to be vertical or horizontal.
if (aDir2d.IsParallel(gp::DX2d(), Precision::Angular()))
{
// Horizontal line. V = const.
theIsU = Standard_False;
theParam = aLoc2d.Y();
theIsForward = aDir2d.Dot(gp::DX2d()) > 0.0;
return Standard_True;
}
else if (aDir2d.IsParallel(gp::DY2d(), Precision::Angular()))
{
// Vertical line. U = const.
theIsU = Standard_True;
theParam = aLoc2d.X();
theIsForward = aDir2d.Dot(gp::DY2d()) > 0.0;
return Standard_True;
}
return Standard_False;
}
#include <GeomLib.hxx>
//=============================================================================
//function : buildC3dOnIsoLine
//purpose :
//=============================================================================
Standard_Boolean Approx_CurveOnSurface::buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
const Standard_Boolean theIsU,
const Standard_Real theParam,
const Standard_Boolean theIsForward)
{
// Convert adapter to the appropriate type.
Handle(GeomAdaptor_HSurface) aGeomAdapter = Handle(GeomAdaptor_HSurface)::DownCast(mySurf);
if (aGeomAdapter.IsNull())
return Standard_False;
if (mySurf->GetType() == GeomAbs_Sphere)
return Standard_False;
// Extract isoline
Handle(Geom_Surface) aSurf = aGeomAdapter->ChangeSurface().Surface();
Handle(Geom_Curve) aC3d;
gp_Pnt2d aF2d = theC2D->Value(theC2D->FirstParameter());
gp_Pnt2d aL2d = theC2D->Value(theC2D->LastParameter());
if (theIsU)
{
aC3d = aSurf->UIso(theParam);
aC3d = new Geom_TrimmedCurve(aC3d, aF2d.Y(), aL2d.Y());
}
else
{
aC3d = aSurf->VIso(theParam);
aC3d = new Geom_TrimmedCurve(aC3d, aF2d.X(), aL2d.X());
}
// Convert arbitrary curve type to the b-spline.
myCurve3d = GeomConvert::CurveToBSplineCurve(aC3d, Convert_QuasiAngular);
if (!theIsForward)
myCurve3d->Reverse();
// Rebuild parameterization for the 3d curve to have the same parameterization with
// a two-dimensional curve.
TColStd_Array1OfReal aKnots = myCurve3d->Knots();
BSplCLib::Reparametrize(theC2D->FirstParameter(), theC2D->LastParameter(), aKnots);
myCurve3d->SetKnots(aKnots);
// Evaluate error.
myError3d = 0.0;
const Standard_Real aParF = myFirst;
const Standard_Real aParL = myLast;
const Standard_Integer aNbPnt = 23;
for(Standard_Integer anIdx = 0; anIdx <= aNbPnt; ++anIdx)
{
const Standard_Real aPar = aParF + ((aParL - aParF) * anIdx) / aNbPnt;
const gp_Pnt2d aPnt2d = theC2D->Value(aPar);
const gp_Pnt aPntC3D = myCurve3d->Value(aPar);
const gp_Pnt aPntC2D = mySurf->Value(aPnt2d.X(), aPnt2d.Y());
const Standard_Real aSqDeviation = aPntC3D.SquareDistance(aPntC2D);
myError3d = Max(aSqDeviation, myError3d);
}
myError3d = Sqrt(myError3d);
// Target tolerance is not obtained. This situation happens for isolines on the sphere.
// OCCT is unable to convert it keeping original parameterization, while the geometric
// form of the result is entirely identical. In that case, it is better to utilize
// a general-purpose approach.
if (myError3d > myTol)
return Standard_False;
return Standard_True;
}

View File

@@ -40,9 +40,22 @@ public:
DEFINE_STANDARD_ALLOC
//! This constructor calls perform method. This constructor is deprecated.
Standard_DEPRECATED("This constructor is deprecated. Use other constructor and perform method instead.")
Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D, const Handle(Adaptor3d_HSurface)& Surf, const Standard_Real First, const Standard_Real Last, const Standard_Real Tol, const GeomAbs_Shape Continuity, const Standard_Integer MaxDegree, const Standard_Integer MaxSegments, const Standard_Boolean Only3d = Standard_False, const Standard_Boolean Only2d = Standard_False);
//! This constructor does not call perform method.
//! @param theC2D 2D Curve to be approximated in 3D.
//! @param theSurf Surface where 2D curve is located.
//! @param theFirst First parameter of resulting curve.
//! @param theFirst Last parameter of resulting curve.
//! @param theTol Computation tolerance.
Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Real theFirst,
const Standard_Real theLast,
const Standard_Real theTol);
Standard_EXPORT Standard_Boolean IsDone() const;
Standard_EXPORT Standard_Boolean HasResult() const;
@@ -59,18 +72,64 @@ public:
//! 2d Curve
Standard_EXPORT Standard_Real MaxError2dV() const;
//! Constructs the 3d curve. Input parameters are ignored when the input curve is
//! U-isoline or V-isoline.
//! @param theMaxSegments Maximal number of segments in the resulting spline.
//! @param theMaxDegree Maximal degree of the result.
//! @param theContinuity Resulting continuity.
//! @param theOnly3d Determines building only 3D curve.
//! @param theOnly2d Determines building only 2D curve.
Standard_EXPORT void Perform(const Standard_Integer theMaxSegments,
const Standard_Integer theMaxDegree,
const GeomAbs_Shape theContinuity,
const Standard_Boolean theOnly3d = Standard_False,
const Standard_Boolean theOnly2d = Standard_False);
protected:
//! Checks whether the 2d curve is a isoline. It can be represented by b-spline, bezier,
//! or geometric line. This line should have natural parameterization.
//! @param theC2D Trimmed curve to be checked.
//! @param theIsU Flag indicating that line is u const.
//! @param theParam Line parameter.
//! @param theIsForward Flag indicating forward parameterization on a isoline.
//! @return Standard_True when 2d curve is a line and Standard_False otherwise.
Standard_Boolean isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
Standard_Boolean& theIsU,
Standard_Real& theParam,
Standard_Boolean& theIsForward) const;
//! Builds 3D curve for a isoline. This method takes corresponding isoline from
//! the input surface.
//! @param theC2D Trimmed curve to be approximated.
//! @param theIsU Flag indicating that line is u const.
//! @param theParam Line parameter.
//! @param theIsForward Flag indicating forward parameterization on a isoline.
//! @return Standard_True when 3d curve is built and Standard_False otherwise.
Standard_Boolean buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
const Standard_Boolean theIsU,
const Standard_Real theParam,
const Standard_Boolean theIsForward);
private:
Approx_CurveOnSurface& operator= (const Approx_CurveOnSurface&);
private:
//! Input curve.
const Handle(Adaptor2d_HCurve2d) myC2D;
//! Input surface.
const Handle(Adaptor3d_HSurface) mySurf;
//! First parameter of the result.
const Standard_Real myFirst;
//! Last parameter of the result.
const Standard_Real myLast;
//! Tolerance.
Standard_Real myTol;
Handle(Geom2d_BSplineCurve) myCurve2d;
Handle(Geom_BSplineCurve) myCurve3d;

View File

@@ -70,12 +70,6 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -131,7 +125,6 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@@ -70,12 +70,6 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -131,7 +125,6 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@@ -25,7 +25,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Aspect_DisplayConnection,Standard_Transient)
// =======================================================================
Aspect_DisplayConnection::Aspect_DisplayConnection()
{
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
myDisplay = NULL;
myIsOwnDisplay = false;
OSD_Environment anEnv ("DISPLAY");
@@ -40,7 +40,7 @@ Aspect_DisplayConnection::Aspect_DisplayConnection()
// =======================================================================
Aspect_DisplayConnection::~Aspect_DisplayConnection()
{
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
if (myDisplay != NULL
&& myIsOwnDisplay)
{
@@ -49,7 +49,7 @@ Aspect_DisplayConnection::~Aspect_DisplayConnection()
#endif
}
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
// =======================================================================
// function : Aspect_DisplayConnection
// purpose :

View File

@@ -20,7 +20,7 @@
#include <TCollection_AsciiString.hxx>
#include <NCollection_DataMap.hxx>
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
#include <InterfaceGraphic.hxx>
#endif
@@ -39,7 +39,7 @@ public:
//! Destructor. Close opened connection.
Standard_EXPORT ~Aspect_DisplayConnection();
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
//! Constructor. Creates connection with display specified in theDisplayName.
//! Display name should be in format "hostname:number" or "hostname:number.screen_number", where:
//! hostname - Specifies the name of the host machine on which the display is physically attached.

View File

@@ -14,7 +14,7 @@
#ifndef _Aspect_FBConfig_HeaderFile
#define _Aspect_FBConfig_HeaderFile
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
typedef struct __GLXFBConfigRec* GLXFBConfig;
typedef GLXFBConfig Aspect_FBConfig; // GLXFBConfig* under UNIX
#else

View File

@@ -59,7 +59,7 @@ public:
virtual void Unmap() const Standard_OVERRIDE { myIsMapped = Standard_False; }
//! Resize window - do nothing.
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
//! Map window - do nothing.
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }

View File

@@ -58,7 +58,7 @@ public:
Standard_EXPORT virtual void Unmap() const = 0;
//! Apply the resizing to the window <me>.
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() const = 0;
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() = 0;
//! Apply the mapping change to the window <me>.
//! and returns TRUE if the window is mapped at screen.

View File

@@ -14,7 +14,7 @@
#ifndef __Aspect_WNTXWD_HXX
# define __Aspect_WNTXWD_HXX
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
# include <X11/XWDFile.h>
# else

View File

@@ -305,27 +305,30 @@ void BOPAlgo_ArgumentAnalyzer::TestTypes()
return;
}
//
if (myOperation != BOPAlgo_UNKNOWN &&
myOperation != BOPAlgo_COMMON)
{
Standard_Integer iDimMin[2], iDimMax[2];
BOPTools_AlgoTools::Dimensions(myShape1, iDimMin[0], iDimMax[0]);
BOPTools_AlgoTools::Dimensions(myShape2, iDimMin[1], iDimMax[1]);
Standard_Boolean bBadTypes =
((myOperation == BOPAlgo_FUSE) &&
(iDimMin[0] != iDimMax[0] || iDimMin[1] != iDimMax[1] || iDimMin[0] != iDimMin[1])) ||
((myOperation == BOPAlgo_CUT) && (iDimMax[0] > iDimMin[1])) ||
((myOperation == BOPAlgo_CUT21) && (iDimMin[0] < iDimMax[1]));
if (bBadTypes) {
BOPAlgo_CheckResult aResult;
aResult.SetShape1(myShape1);
aResult.SetShape2(myShape2);
aResult.SetCheckStatus(BOPAlgo_BadType);
myResult.Append(aResult);
Standard_Integer aDim1, aDim2;
Standard_Boolean bBadTypes = Standard_False;
//
aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
if (aDim1 < aDim2) {
if (myOperation == BOPAlgo_FUSE ||
myOperation == BOPAlgo_CUT21) {
bBadTypes = Standard_True;
}
}
else if (aDim1 > aDim2) {
if (myOperation == BOPAlgo_FUSE ||
myOperation == BOPAlgo_CUT) {
bBadTypes = Standard_True;
}
}
if (bBadTypes) {
BOPAlgo_CheckResult aResult;
aResult.SetShape1(myShape1);
aResult.SetShape2(myShape2);
aResult.SetCheckStatus(BOPAlgo_BadType);
myResult.Append(aResult);
}
}
}
//=======================================================================

View File

@@ -122,7 +122,7 @@ BOPAlgo_Operation BOPAlgo_BOP::Operation()const
//=======================================================================
void BOPAlgo_BOP::CheckData()
{
Standard_Integer i, j, aNbArgs, aNbTools;
Standard_Integer i, j, iDim, aNbArgs, aNbTools;
Standard_Boolean bFuse;
TopTools_ListIteratorOfListOfShape aItLS;
//
@@ -164,8 +164,7 @@ void BOPAlgo_BOP::CheckData()
// or equal to the MAXIMAL dimension of the TOOLS;
// 4. COMMON: The arguments and tools could have any dimensions.
//
Standard_Integer iDimMin[2] = { 3, 3 },
iDimMax[2] = { 0, 0 };
Standard_Integer iDimMin[2] = { 0, 0 }, iDimMax[2] = { 0, 0 };
Standard_Boolean bHasValid[2] = {Standard_False, Standard_False};
//
for (i=0; i<2; ++i) {
@@ -174,27 +173,38 @@ void BOPAlgo_BOP::CheckData()
for (j=0; aItLS.More(); aItLS.Next(), ++j) {
const TopoDS_Shape& aS=aItLS.Value();
Standard_Boolean bIsEmpty = BOPTools_AlgoTools3D::IsEmptyShape(aS);
if (bIsEmpty)
{
if (bIsEmpty) {
AddWarning(new BOPAlgo_AlertEmptyShape (aS));
continue;
}
Standard_Integer iDMin, iDMax;
BOPTools_AlgoTools::Dimensions(aS, iDMin, iDMax);
if (iDMin < iDimMin[i])
iDimMin[i] = iDMin;
if (iDMax > iDimMax[i])
iDimMax[i] = iDMax;
if (bFuse && (iDimMin[i] != iDimMax[i]))
{
//
iDim = BOPTools_AlgoTools::Dimension(aS);
if (iDim < 0) {
// non-homogeneous argument
AddError (new BOPAlgo_AlertBOPNotAllowed);
return;
}
//
bHasValid[i] = Standard_True;
//
if (!j) {
iDimMin[i] = iDim;
iDimMax[i] = iDim;
continue;
}
//
if (iDim < iDimMin[i]) {
iDimMin[i] = iDim;
}
else if (iDim > iDimMax[i]) {
iDimMax[i] = iDim;
}
//
if (bFuse && (iDimMin[i] != iDimMax[i])) {
// non-homogeneous argument
AddError (new BOPAlgo_AlertBOPNotAllowed);
return;
}
}
}
//
@@ -212,7 +222,7 @@ void BOPAlgo_BOP::CheckData()
if (bHasValid[0] || bHasValid[1])
{
// In case of all empty shapes in one of the groups
// this group acquires the dimension of other group
// this group aquires the dimension of other group
myDims[0] = bHasValid[0] ? iDimMin[0] : iDimMin[1];
myDims[1] = bHasValid[1] ? iDimMin[1] : iDimMin[0];
}
@@ -573,17 +583,12 @@ void BOPAlgo_BOP::BuildRC()
aItLS.Initialize(aLS);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aS = aItLS.Value();
TopTools_ListOfShape aList;
BOPTools_AlgoTools::TreatCompound (aS, aList);
for (TopTools_ListOfShape::Iterator itList (aList); itList.More(); itList.Next())
{
const TopoDS_Shape& aSS = itList.Value();
iDim = BOPTools_AlgoTools::Dimension (aSS);
if (iDim < 0)
continue;
aType = TypeToExplore (iDim);
TopExp::MapShapes (aSS, aType, aMS);
iDim = BOPTools_AlgoTools::Dimension(aS);
if (iDim < 0) {
continue;
}
aType = TypeToExplore(iDim);
TopExp::MapShapes(aS, aType, aMS);
}
}
//
@@ -925,7 +930,7 @@ void BOPAlgo_BOP::BuildShape()
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aS = aItLS.Value();
BOPTools_AlgoTools::TreatCompound(aS, aLSNonCont, &aMInpFence);
BOPAlgo_Tools::TreatCompound(aS, aMInpFence, aLSNonCont);
}
}

View File

@@ -441,7 +441,7 @@ void BOPAlgo_Builder::BuildBOP(const TopTools_ListOfShape& theObjects,
{
TopTools_ListOfShape aLS;
TopTools_MapOfShape aMFence;
BOPTools_AlgoTools::TreatCompound(aS, aLS, &aMFence);
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLS);
TopTools_ListOfShape::Iterator it(aLS);
for (; it.More(); it.Next())

View File

@@ -550,7 +550,7 @@ void BOPAlgo_Builder::FillInternalShapes()
aIt.Initialize(aArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
BOPTools_AlgoTools::TreatCompound(aS, aLSC, &aMFence);
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
}
aIt.Initialize(aLSC);
for (; aIt.More(); aIt.Next()) {

View File

@@ -141,50 +141,44 @@ void BOPAlgo_CellsBuilder::IndexParts()
TopTools_ListIteratorOfListOfShape aIt(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
TopTools_ListOfShape aLSubS;
BOPTools_AlgoTools::TreatCompound (aS, aLSubS);
for (TopTools_ListOfShape::Iterator itSub (aLSubS); itSub.More(); itSub.Next())
{
const TopoDS_Shape& aSS = itSub.Value();
Standard_Integer iDim = BOPTools_AlgoTools::Dimension (aSS);
aMDims.Add(iDim);
TopAbs_ShapeEnum aType = TypeToExplore (iDim);
TopExp_Explorer aExp (aSS, aType);
for (; aExp.More(); aExp.Next())
{
const TopoDS_Shape& aST = aExp.Current();
const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
if (!pLSIm) {
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aST)) {
aBB.Add(anAllParts, aST);
}
//
continue;
//
Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
aMDims.Add(iDim);
TopAbs_ShapeEnum aType = TypeToExplore(iDim);
//
TopExp_Explorer aExp(aS, aType);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aST = aExp.Current();
const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
if (!pLSIm) {
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aST)) {
aBB.Add(anAllParts, aST);
}
//
TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSTIm = aItIm.Value();
//
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aSTIm)) {
aBB.Add(anAllParts, aSTIm);
}
} // for (; aItIm.More(); aItIm.Next()) {
} // for (; aExp.More(); aExp.Next()) {
} // for (; itSub.More(); itSub.Next())
continue;
}
//
TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSTIm = aItIm.Value();
//
TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
if (!pLS) {
pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
}
pLS->Append(aS);
//
if (aMFence.Add(aSTIm)) {
aBB.Add(anAllParts, aSTIm);
}
} // for (; aItIm.More(); aItIm.Next()) {
} // for (; aExp.More(); aExp.Next()) {
} // for (; aIt.More(); aIt.Next()) {
//
myAllParts = anAllParts;

View File

@@ -75,7 +75,7 @@ void BOPAlgo_MakeConnected::CheckData()
TopTools_ListIteratorOfListOfShape itLA(myArguments);
for (; itLA.More(); itLA.Next())
BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLA, &aMFence);
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLA);
if (aLA.IsEmpty())
{
@@ -197,7 +197,7 @@ void BOPAlgo_MakeConnected::AssociateMaterials()
// Extract all non-compound shapes from the result
TopTools_ListOfShape aLShapes;
TopTools_MapOfShape aMFence;
BOPTools_AlgoTools::TreatCompound(myShape, aLShapes, &aMFence);
BOPAlgo_Tools::TreatCompound(myShape, aMFence, aLShapes);
if (aLShapes.IsEmpty())
return;

View File

@@ -342,7 +342,7 @@ void BOPAlgo_MakerVolume::FillInternalShapes(const TopTools_ListOfShape& theLSR)
TopTools_ListOfShape::Iterator itLA(myDS->Arguments());
for (; itLA.More(); itLA.Next())
BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLSC, &aMFence);
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLSC);
// Get only edges and vertices from arguments
TopTools_ListOfShape aLVE;

View File

@@ -225,14 +225,6 @@ void BOPAlgo_PaveFiller::IntersectVE
const Handle(BOPDS_PaveBlock)& aPB = theVEPairs.FindKey(i);
Standard_Integer nE = aPB->OriginalEdge();
//
TColStd_MapOfInteger aMVPB;
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next())
{
aMVPB.Add (itPB.Value()->Pave1().Index());
aMVPB.Add (itPB.Value()->Pave2().Index());
}
const TColStd_ListOfInteger& aLV = theVEPairs(i);
TColStd_ListIteratorOfListOfInteger aItLV(aLV);
for (; aItLV.More(); aItLV.Next()) {
@@ -241,9 +233,6 @@ void BOPAlgo_PaveFiller::IntersectVE
Standard_Integer nVSD = nV;
myDS->HasShapeSD(nV, nVSD);
//
if (aMVPB.Contains (nVSD))
continue;
BOPDS_Pair aPair(nVSD, nE);
TColStd_ListOfInteger* pLI = aDMVSD.ChangeSeek(aPair);
if (pLI) {
@@ -298,21 +287,7 @@ void BOPAlgo_PaveFiller::IntersectVE
Standard_Integer nVx = UpdateVertex(nV, aTolVNew);
// 2. Create new pave and add it as extra pave to pave block
// for further splitting of the edge
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
// Find the appropriate one
Handle(BOPDS_PaveBlock) aPB;
BOPDS_ListOfPaveBlock::Iterator itPB (aLPB);
for (; itPB.More(); itPB.Next())
{
aPB = itPB.Value();
Standard_Real aT1, aT2;
aPB->Range (aT1, aT2);
if (aT > aT1 && aT < aT2)
break;
}
if (!itPB.More())
continue;
const Handle(BOPDS_PaveBlock)& aPB = aVESolver.PaveBlock();
BOPDS_Pave aPave;
aPave.SetIndex(nVx);
aPave.SetParameter(aT);

View File

@@ -1002,7 +1002,6 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
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())
@@ -1035,30 +1034,25 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
aPB2->Range(aT21, aT22);
// Check the angle between edges in the middle point.
// If the angle is more than 25 degrees, do not use the additional
// 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;
{
GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
aProjPC.Perform(aPm);
if (!aProjPC.NbPoints())
continue;
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.9063)
bUseAddTol = Standard_False;
}
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);
if (Abs(aCos) < 0.984)
bUseAddTol = Standard_False;
}
// Add pair for intersection

View File

@@ -847,7 +847,6 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// 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
@@ -887,7 +886,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
// 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
// of the face is not in the range of 80 - 100 degrees, do not use the additional
// tolerance, as it may lead to undesired unification of edge with the face.
Standard_Boolean bUseAddTol = Standard_True;
@@ -927,19 +926,15 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
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())
{
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 25 degrees.
Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
if (Abs(aCos) > 0.4226)
bUseAddTol = Standard_False;
}
// Angle between vectors should be close to 90 degrees.
// We allow deviation of 10 degrees.
Standard_Real aCos = aVFNorm.Dot(aVETgt);
if (Abs(aCos) > 0.174)
bUseAddTol = Standard_False;
}
// Compute an addition to Fuzzy value

View File

@@ -2414,7 +2414,7 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
Standard_Integer nVUsed;
Standard_Real aPTol, aDTol;
//
aDTol = BOPTools_AlgoTools::DTolerance();
aDTol = 1.e-12;
//
GeomAdaptor_Curve aGAC(aIC.Curve());
aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
@@ -2459,8 +2459,7 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
aTolV = BRep_Tool::Tolerance(aV);
gp_Pnt aP2 = BRep_Tool::Pnt(aV);
Standard_Real aDist = aP1.Distance(aP2);
if (aTolV < aDist + aDTol)
{
if (aDist > aTolV) {
BRep_Builder().UpdateVertex(aV, aDist + aDTol);
//
if (!aMVTol.IsBound(nV)) {
@@ -2832,7 +2831,7 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
if (aDistVP > aTolV)
{
Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance());
Standard_Integer nVn = UpdateVertex(nV, aDistVP);
if (nVn != nV)
{
aPave.SetIndex(nVn);

View File

@@ -784,7 +784,7 @@ void UpdateVertices(const TopoDS_Edge& aE,
aD2=aP3D.SquareDistance(aP3Dx);
if (aD2>aTolV2) {
aD=sqrt(aD2);
aBB.UpdateVertex(aV[j], aD + BOPTools_AlgoTools::DTolerance());
aBB.UpdateVertex(aV[j], aD);
}
}
}

View File

@@ -181,7 +181,7 @@ void BOPAlgo_RemoveFeatures::CheckData()
TopTools_ListOfShape aShapes;
TopTools_MapOfShape aMFence;
// Extract all shapes from the compound
BOPTools_AlgoTools::TreatCompound(myInputShape, aShapes, &aMFence);
BOPAlgo_Tools::TreatCompound(myInputShape, aMFence, aShapes);
if (aShapes.IsEmpty())
{
// Add error of empty input shape

View File

@@ -1103,6 +1103,29 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal&
}
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void BOPAlgo_Tools::TreatCompound(const TopoDS_Shape& theS,
TopTools_MapOfShape& aMFence,
TopTools_ListOfShape& theLS)
{
TopAbs_ShapeEnum aType = theS.ShapeType();
if (aType != TopAbs_COMPOUND)
{
if (aMFence.Add(theS))
theLS.Append(theS);
return;
}
TopoDS_Iterator aIt(theS);
for (; aIt.More(); aIt.Next())
{
const TopoDS_Shape& aS = aIt.Value();
TreatCompound(aS, aMFence, theLS);
}
}
//=======================================================================
// Classification of the faces relatively solids
//=======================================================================

View File

@@ -165,6 +165,13 @@ public:
const Standard_Real theFuzzyValue,
TopTools_ListOfListOfShape& theChains);
//! Collect in the output list recursively all non-compound subshapes of the first level
//! of the given shape theS. If a shape presents in the map theMFence it is skipped.
//! All shapes put in the output are also added into theMFence.
Standard_EXPORT static void TreatCompound(const TopoDS_Shape& theS,
TopTools_MapOfShape& theMFence,
TopTools_ListOfShape& theLS);
//! Classifies the faces <theFaces> relatively solids <theSolids>.
//! The IN faces for solids are stored into output data map <theInParts>.
//!

View File

@@ -94,7 +94,6 @@ static
static
void Path (const GeomAdaptor_Surface& aGAS,
const TopoDS_Face& myFace,
const MyDataMapOfShapeBoolean& aVertMap,
const TopoDS_Vertex& aVa,
const TopoDS_Edge& aEOuta,
BOPAlgo_EdgeInfo& anEdgeInfo,
@@ -102,7 +101,8 @@ static
TopTools_SequenceOfShape& aVertVa,
TColgp_SequenceOfPnt2d& aCoordVa,
BOPTools_ConnexityBlock& aCB,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
MyDataMapOfShapeBoolean aVertMap);
static
Standard_Real Angle (const gp_Dir2d& aDir2D);
@@ -122,6 +122,7 @@ static
static
void RefineAngles(const TopoDS_Face& myFace,
const TopTools_ListOfShape&,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&,
const Handle(IntTools_Context)&);
@@ -129,6 +130,7 @@ static
static
void RefineAngles(const TopoDS_Vertex& ,
const TopoDS_Face& ,
const TopTools_MapOfShape& ,
BOPAlgo_ListOfEdgeInfo&,
const Handle(IntTools_Context)&);
@@ -322,7 +324,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
//Theme: The treatment p-curves convergent in node.
//The refining the angles of p-curves taking into account
//bounding curves if exist.
RefineAngles(myFace, mySmartMap, theContext);
RefineAngles(myFace, myEdges, mySmartMap, theContext);
//
// 4. Do
//
@@ -346,8 +348,8 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
aVertVa.Clear();
aCoordVa.Clear();
//
Path(aGAS, myFace, aVertMap, aVa, aEOuta, aEI, aLS,
aVertVa, aCoordVa, aCB, mySmartMap);
Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
aVertVa, aCoordVa, aCB, mySmartMap, aVertMap);
}
}
}// for (i=1; i<=aNb; ++i) {
@@ -358,7 +360,6 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
//=======================================================================
void Path (const GeomAdaptor_Surface& aGAS,
const TopoDS_Face& myFace,
const MyDataMapOfShapeBoolean& aVertMap,
const TopoDS_Vertex& aVFirst,
const TopoDS_Edge& aEFirst,
BOPAlgo_EdgeInfo& aEIFirst,
@@ -366,7 +367,8 @@ void Path (const GeomAdaptor_Surface& aGAS,
TopTools_SequenceOfShape& aVertVa,
TColgp_SequenceOfPnt2d& aCoordVa,
BOPTools_ConnexityBlock& aCB,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
MyDataMapOfShapeBoolean aVertMap)
{
Standard_Integer i, j, aNb, aNbj;
Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
@@ -383,8 +385,6 @@ void Path (const GeomAdaptor_Surface& aGAS,
BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
//
aTwoPI = M_PI + M_PI;
NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeq;
//
// append block
//
@@ -401,7 +401,6 @@ void Path (const GeomAdaptor_Surface& aGAS,
anEdgeInfo->SetPassed(Standard_True);
aLS.Append(aEOuta);
aVertVa.Append(aVa);
anInfoSeq.Append (anEdgeInfo);
TopoDS_Vertex pVa=aVa;
pVa.Orientation(TopAbs_FORWARD);
@@ -482,7 +481,6 @@ void Path (const GeomAdaptor_Surface& aGAS,
//
TopTools_SequenceOfShape aLSt, aVertVat;
TColgp_SequenceOfPnt2d aCoordVat;
NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeqTmp;
//
aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
//
@@ -490,16 +488,15 @@ void Path (const GeomAdaptor_Surface& aGAS,
aLSt.Append(aLS(j));
aVertVat.Append(aVertVa(j));
aCoordVat.Append(aCoordVa(j));
anInfoSeqTmp.Append (anInfoSeq (j));
}
//
aLS.Clear();
aVertVa.Clear();
aCoordVa.Clear();
aLS=aLSt;
aVertVa=aVertVat;
aCoordVa=aCoordVat;
anInfoSeq = anInfoSeqTmp;
aEOuta = TopoDS::Edge (aLS.Last());
anEdgeInfo = anInfoSeq.Last();
//
break;
}
@@ -883,15 +880,48 @@ Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
//purpose :
//=======================================================================
void RefineAngles(const TopoDS_Face& myFace,
const TopTools_ListOfShape& myEdges,
BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
const Handle(IntTools_Context)& theContext)
{
const Standard_Integer aNb = mySmartMap.Extent();
for (Standard_Integer i = 1; i <= aNb; ++i)
{
const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&mySmartMap.FindKey (i));
BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap (i);
RefineAngles(aV, myFace, aLEI, theContext);
Standard_Integer aNb, i;
NCollection_IndexedDataMap<TopoDS_Shape,
Standard_Integer,
TopTools_ShapeMapHasher> aMSI;
TopTools_MapOfShape aMBE;
TopTools_ListIteratorOfListOfShape aIt;
//
// 1. Boundary Edges
aIt.Initialize(myEdges);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
if(aMSI.Contains(aE)) {
Standard_Integer& iCnt = aMSI.ChangeFromKey(aE);
++iCnt;
}
else {
Standard_Integer iCnt = 1;
aMSI.Add(aE, iCnt);
}
}
//
aNb = aMSI.Extent();
for (i = 1; i <= aNb; ++i) {
Standard_Integer iCnt = aMSI(i);
if (iCnt == 1) {
const TopoDS_Shape& aE = aMSI.FindKey(i);
aMBE.Add(aE);
}
}
//
aMSI.Clear();
//
aNb = mySmartMap.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&mySmartMap.FindKey(i));
BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
//
RefineAngles(aV, myFace, aMBE, aLEI, theContext);
}
}
//=======================================================================
@@ -907,6 +937,7 @@ typedef TopTools_DataMapOfShapeReal::Iterator \
//=======================================================================
void RefineAngles(const TopoDS_Vertex& aV,
const TopoDS_Face& myFace,
const TopTools_MapOfShape& aMBE,
BOPAlgo_ListOfEdgeInfo& aLEI,
const Handle(IntTools_Context)& theContext)
{
@@ -923,10 +954,11 @@ void RefineAngles(const TopoDS_Vertex& aV,
aItLEI.Initialize(aLEI);
for (; aItLEI.More(); aItLEI.Next()) {
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
bIsIn=aEI.IsIn();
aA=aEI.Angle();
//
if (!aEI.IsInside()) {
if (aMBE.Contains(aE)) {
++iCntBnd;
if (!bIsIn) {
aA1=aA;
@@ -950,7 +982,7 @@ void RefineAngles(const TopoDS_Vertex& aV,
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
//
bIsBoundary=!aEI.IsInside();
bIsBoundary=aMBE.Contains(aE);
bIsIn=aEI.IsIn();
if (bIsBoundary || bIsIn) {
continue;

View File

@@ -1636,7 +1636,7 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
TopoDS_Edge& theE)
{
BRep_Builder aBB;
Standard_Real aNeedTol = theTolR3D + BOPTools_AlgoTools::DTolerance();
Standard_Real aNeedTol = theTolR3D + 1e-12;
//
aBB.UpdateVertex(theV1, aNeedTol);
aBB.UpdateVertex(theV2, aNeedTol);

View File

@@ -32,7 +32,6 @@
#include <TopAbs_ShapeEnum.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <Precision.hxx>
@@ -61,15 +60,6 @@ public:
DEFINE_STANDARD_ALLOC
public: //! @name Constants
//! Additional tolerance (delta tolerance) is used in Boolean Operations
//! to ensure that the tolerance of new/old entities obtained
//! by intersection of two shapes is slightly bigger than the actual
//! distances to these shapes. It helps to avoid numerical instability
//! which may occur when comparing distances and tolerances.
static Standard_Real DTolerance() { return 1.e-12; }
public: //! @name Intersection of the vertices
//! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>.
@@ -562,22 +552,9 @@ public: //! @name Other methods
const TopoDS_Edge& aE,
const Handle(IntTools_Context)& aContext);
//! Returns the min and max dimensions of the shape <theS>.
Standard_EXPORT static void Dimensions (const TopoDS_Shape& theS,
Standard_Integer& theDMin,
Standard_Integer& theDMax);
//! Returns dimension of the shape <theS>.
//! If the shape contains elements of different dimension, -1 is returned.
//! Retutns dimension of the shape <theS>.
Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS);
//! Collects in the output list recursively all non-compound sub-shapes of the first level
//! of the given shape theS. The optional map theMap is used to avoid the duplicates in the
//! output list, so it will also contain all non-compound sub-shapes.
Standard_EXPORT static void TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theList,
TopTools_MapOfShape* theMap = NULL);
//! Returns true if the shell <theShell> is open
Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell);

View File

@@ -823,7 +823,7 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
Standard_Boolean SameRange = TE->SameRange();
Standard_Real First = myHCurve->FirstParameter();
Standard_Real Last = myHCurve->LastParameter();
Standard_Real Delta = BOPTools_AlgoTools::DTolerance();
Standard_Real Delta =1.e-12;
Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
const TopLoc_Location& Floc = S.Location();

View File

@@ -34,6 +34,10 @@
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
static
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX);
//=======================================================================
// function: UpdateVertex
// purpose:
@@ -42,7 +46,7 @@ void BOPTools_AlgoTools::UpdateVertex
(const TopoDS_Vertex& aVF,
const TopoDS_Vertex& aNewVertex)
{
Standard_Real aTolVF, aTolNewVertex, aDist, aNewTol;
Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
//
gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
@@ -54,7 +58,7 @@ void BOPTools_AlgoTools::UpdateVertex
if (aNewTol>aTolVF) {
BRep_Builder BB;
BB.UpdateVertex (aVF, aNewTol + BOPTools_AlgoTools::DTolerance());
BB.UpdateVertex (aVF, aNewTol+aDTol);
}
}
@@ -66,7 +70,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist, aFirst, aLast;
Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
@@ -77,7 +81,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
BB.UpdateVertex (aV, aDist+aDTol);
}
}
//
@@ -89,7 +93,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist;
Standard_Real aTolV, aDist, aDTol=1.e-12;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
@@ -100,7 +104,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
BB.UpdateVertex (aV, aDist+aDTol);
}
}
//=======================================================================
@@ -265,7 +269,7 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
const TopoDS_Face& aF1,
TopoDS_Vertex& aNewVertex)
{
Standard_Real aTol1, aTol2, aMaxTol;
Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
gp_Pnt aPnt;
PointOnEdge (aE1, aParm1, aPnt);
@@ -273,7 +277,8 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
aTol1=BRep_Tool::Tolerance(aE1);
aTol2=BRep_Tool::Tolerance(aF1);
//
aMaxTol = aTol1 + aTol2 + BOPTools_AlgoTools::DTolerance();
//aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
aMaxTol=aTol1+aTol2+delta;
//
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
@@ -432,101 +437,103 @@ void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
}
}
}
namespace
{
//=======================================================================
//function : dimension
//purpose : returns dimension of elementary shape
//=======================================================================
static Standard_Integer dimension (const TopoDS_Shape& theS)
{
switch (theS.ShapeType())
{
case TopAbs_VERTEX:
return 0;
case TopAbs_EDGE:
case TopAbs_WIRE:
return 1;
case TopAbs_FACE:
case TopAbs_SHELL:
return 2;
case TopAbs_SOLID:
case TopAbs_COMPSOLID:
return 3;
default:
return -1;
}
}
}
//=======================================================================
//function : Dimensions
//purpose :
//=======================================================================
void BOPTools_AlgoTools::Dimensions (const TopoDS_Shape& theS,
Standard_Integer& theDMin,
Standard_Integer& theDMax)
{
theDMin = theDMax = dimension (theS);
if (theDMax >= 0)
return;
TopTools_ListOfShape aLS;
TopTools_MapOfShape aMFence;
TreatCompound (theS, aLS, &aMFence);
if (aLS.IsEmpty())
{
// empty shape
theDMin = theDMax = -1;
return;
}
theDMin = 3;
theDMax = 0;
for (TopTools_ListOfShape::Iterator it (aLS); it.More(); it.Next())
{
Standard_Integer aDim = dimension (it.Value());
if (aDim < theDMin)
theDMin = aDim;
if (aDim > theDMax)
theDMax = aDim;
}
}
//=======================================================================
//function : Dimension
//purpose :
//=======================================================================
Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
{
Standard_Integer aDMin, aDMax;
Dimensions (theS, aDMin, aDMax);
return (aDMin == aDMax) ? aDMin : -1;
Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
TopAbs_ShapeEnum aTS;
TopTools_ListOfShape aLS;
TopTools_ListIteratorOfListOfShape aIt;
//
aTS=theS.ShapeType();
if (aTS!=TopAbs_COMPOUND) {
switch (aTS) {
case TopAbs_EDGE:
case TopAbs_WIRE:
iRet=1;
break;
case TopAbs_FACE:
case TopAbs_SHELL:
iRet=2;
break;
case TopAbs_SOLID:
case TopAbs_COMPSOLID:
iRet=3;
break;
default:
iRet=0;
}
return iRet;
}
//
iRet=-1;
TreatCompound(theS, aLS);
if(aLS.IsEmpty()) {
iRet = -2; //empty compound
return iRet;
}
aIt.Initialize(aLS);
for (i=0; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
iRx=Dimension(aSx);
if (!i) {
iRx0=iRx;
i=1;
continue;
}
if (iRx!=iRx0) {
return iRet;// -1
}
}
return iRx;
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLS,
TopTools_MapOfShape* theMFence)
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX)
{
TopAbs_ShapeEnum aType = theS.ShapeType();
if (aType != TopAbs_COMPOUND)
{
if (!theMFence || theMFence->Add (theS))
{
theLS.Append (theS);
Standard_Integer aNbC1;
TopAbs_ShapeEnum aType;
TopTools_ListOfShape aLC, aLC1;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
TopoDS_Iterator aItC;
//
aLC.Append (theC1);
for(;;) {
aLC1.Clear();
aIt.Initialize(aLC);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aC=aIt.Value(); //C is compound
//
aItC.Initialize(aC);
for (; aItC.More(); aItC.Next()) {
const TopoDS_Shape& aS=aItC.Value();
aType=aS.ShapeType();
if (aType==TopAbs_COMPOUND) {
aLC1.Append(aS);
}
else {
theLSX.Append(aS);
}
}
}
return;
}
for (TopoDS_Iterator it (theS); it.More(); it.Next())
{
TreatCompound (it.Value(), theLS, theMFence);
}
//
aNbC1=aLC1.Extent();
if (!aNbC1) {
break;
}
//
aLC.Clear();
aIt.Initialize(aLC1);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSC=aIt.Value();
aLC.Append(aSC);
}
}// while(1)
}

View File

@@ -363,9 +363,8 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
#ifdef OCCT_DEBUG_CHRONO
InitChron(chr_approx);
#endif
Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d,
myContinuity, myMaxDegree, myMaxSeg,
Only3d, Only2d);
Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d);
appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d);
#ifdef OCCT_DEBUG_CHRONO
ResultChron(chr_approx,t_approx);
approx_count++;

View File

@@ -126,8 +126,8 @@ Standard_Real BRepBlend_AppSurface::TolCurveOnSurf(const Standard_Integer Index)
return approx.TolCurveOnSurf(Index);
}
inline void BRepBlend_AppSurface::TolReached (Standard_Real& Tol3d,
Standard_Real& Tol2d) const
void BRepBlend_AppSurface::TolReached (Standard_Real& Tol3d,
Standard_Real& Tol2d) const
{
Tol3d = approx.MaxErrorOnSurf();
Tol2d = 0;

View File

@@ -285,7 +285,14 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
aSelectorLine.SetCurrentLine(L, Par);
Standard_Integer SelsEVL = 0;
SelsEVL = aTree.Select(aSelectorLine); //SelsEE > 0 => Line/Edges & Line/Vertex intersection
if (!aSelectorLine.IsCorrect())
{
// Go to the next segment
isFaultyLine = Standard_True;
continue;
}
if (SelsEVL > 0 )
{
// Line and edges / vertices interference.

View File

@@ -1055,6 +1055,7 @@ void BRepFeat_MakeRevolutionForm::Perform()
if(ex1.Current().IsSame(e1)) {
myLFMap(iter.Key()).Clear();
myLFMap(iter.Key()).Append(ex2.Current());
break; // break the cycle (e1 became a dead reference)
}
ex2.Next();
}
@@ -1062,16 +1063,14 @@ void BRepFeat_MakeRevolutionForm::Perform()
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter1(mySlface);
for(; iter1.More(); iter1.Next()) {
const TopoDS_Shape& f1 = iter1.Key();
const TopoDS_Shape& e1 = iter1.Value().First();
TopExp_Explorer ex1(myPbase, TopAbs_EDGE);
TopExp_Explorer ex2(Pbase, TopAbs_EDGE);
for(; ex1.More(); ex1.Next()) {
const TopoDS_Shape& E1 = ex1.Current();
const TopoDS_Shape& E2 = ex2.Current();
if(E1.IsSame(e1)) {
mySlface(f1).Clear();
mySlface(f1).Append(E2);
if(ex1.Current().IsSame(e1)) {
mySlface(iter1.Key()).Clear();
mySlface(iter1.Key()).Append(ex2.Current());
break; // break the cycle (e1 became a dead reference)
}
ex2.Next();
}
@@ -1158,9 +1157,9 @@ void BRepFeat_MakeRevolutionForm::Perform()
const TopoDS_Shape& sh = it1.Value().First();
exx.Init(VraiForm, TopAbs_FACE);
for(; exx.More(); exx.Next()) {
const TopoDS_Face& fac = TopoDS::Face(exx.Current());
TopoDS_Face fac = TopoDS::Face(exx.Current());
TopExp_Explorer exx1(fac, TopAbs_WIRE);
const TopoDS_Wire& thew = TopoDS::Wire(exx1.Current());
TopoDS_Wire thew = TopoDS::Wire(exx1.Current());
if(thew.IsSame(myFShape)) {
const TopTools_ListOfShape& desfaces = trP.Modified(f2);
myMap(myFShape) = desfaces;
@@ -1172,13 +1171,13 @@ void BRepFeat_MakeRevolutionForm::Perform()
continue;
}
if(fac.IsSame(sh)) {
if (trP.IsDeleted(fac)) {
}
else {
if (! trP.IsDeleted(fac))
{
const TopTools_ListOfShape& desfaces = trP.Modified(fac);
if(!desfaces.IsEmpty()) {
myMap(orig).Clear();
myMap(orig) = trP.Modified(fac);
break; // break the cycle (sh became a dead reference)
}
}
}

View File

@@ -70,12 +70,6 @@ public:
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! Set value of hang checking flag
//! if this flag = true, possible hang of algorithm is checked
//! and algorithm is forced to stop.
//! By default hang checking is used.
Standard_EXPORT void SetHangChecking(const Standard_Boolean theHangChecking);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -131,7 +125,6 @@ private:
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
Standard_Boolean myHangChecking;
};

View File

@@ -149,9 +149,6 @@ static void TrimEdge (const TopoDS_Edge& Edge,
TColStd_SequenceOfReal& ThePar,
TopTools_SequenceOfShape& S);
static TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
const TopoDS_Face& F);
static Standard_Integer PosOnFace (Standard_Real d1,
Standard_Real d2,
Standard_Real d3);
@@ -986,8 +983,8 @@ void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face& Sp,
// skin => same orientation E[0] , inverted orientation E[2]
// if contreskin it is inverted.
//--------------------------------------------------------------
E[0].Orientation(OriEdgeInFace(E[0],F[0]));
E[2].Orientation(OriEdgeInFace(E[2],F[1]));
E[0].Orientation(BRepTools::OriEdgeInFace(E[0],F[0]));
E[2].Orientation(BRepTools::OriEdgeInFace(E[2],F[1]));
if (DistanceToOZ(VF) < DistanceToOZ(VL) ) {
// Skin
@@ -1199,14 +1196,14 @@ void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face& Sp,
TopTools_ListIteratorOfListOfShape itl;
const TopTools_ListOfShape& LF = myMap(CurrentSpine)(VCF);
TopAbs_Orientation Ori = OriEdgeInFace(TopoDS::Edge(LF.First()),
TopAbs_Orientation Ori = BRepTools::OriEdgeInFace(TopoDS::Edge(LF.First()),
CurrentFace);
for (itl.Initialize(LF), itl.Next(); itl.More(); itl.Next()) {
TopoDS_Edge RE = TopoDS::Edge(itl.Value());
MapBis(CurrentFace).Append(RE.Oriented(Ori));
}
const TopTools_ListOfShape& LL = myMap(CurrentSpine)(VCL);
Ori = OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
Ori = BRepTools::OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
for (itl.Initialize(LL), itl.Next() ; itl.More(); itl.Next()) {
TopoDS_Edge RE = TopoDS::Edge(itl.Value());
MapBis(CurrentFace).Append(RE.Oriented(Ori));
@@ -2920,26 +2917,6 @@ static TopAbs_Orientation Relative (const TopoDS_Wire& W1,
return TopAbs_REVERSED;
}
//=======================================================================
//function : OriEdgeInFace
//purpose :
//=======================================================================
TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
const TopoDS_Face& F )
{
TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
for (; Exp.More() ;Exp.Next()) {
if (Exp.Current().IsSame(E)) {
return Exp.Current().Orientation();
}
}
throw Standard_ConstructionError("BRepFill_Evolved::OriEdgeInFace");
}
//=======================================================================
//function : IsOnFace

View File

@@ -31,7 +31,6 @@
#include <BRepFill_FaceAndOrder.hxx>
#include <BRepFill_Filling.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeEdge2d.hxx>
#include <BRepLib_MakeFace.hxx>
@@ -235,6 +234,8 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@@ -257,6 +258,8 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@@ -457,9 +460,7 @@ void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_List
aDist < BRep_Tool::Tolerance(V_edge[j]))
{
MW.Add(CurEdge);
TopoDS_Edge NewEdge = MW.Edge();
myOldNewMap.Bind(CurEdge.Oriented(TopAbs_FORWARD),
NewEdge.Oriented(TopAbs_FORWARD));
myOldNewMap(CurEdge).Append(MW.Edge());
EdgeList.Remove(Itl);
found = Standard_True;
break;
@@ -703,47 +704,25 @@ void BRepFill_Filling::Build()
{
const TopoDS_Edge& InitEdge = myBoundary(i).myEdge;
TopoDS_Edge anEdge = InitEdge;
anEdge.Orientation(TopAbs_FORWARD);
if (myOldNewMap.IsBound(anEdge))
anEdge = TopoDS::Edge(myOldNewMap(anEdge));
if (!myOldNewMap(anEdge).IsEmpty())
anEdge = TopoDS::Edge( myOldNewMap(anEdge).First() );
Handle(Geom2d_Curve) aCurveOnPlate = CurvesOnPlate->Value(i);
TopoDS_Edge NewEdge = TopoDS::Edge(anEdge.EmptyCopied());
TopoDS_Vertex V1, V2, NewV1, NewV2;
TopExp::Vertices(anEdge, V1, V2);
if (myOldNewMap.IsBound(V1))
NewV1 = TopoDS::Vertex(myOldNewMap(V1));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V1);
NewV1 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV1, dmax);
myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), NewV1);
}
if (myOldNewMap.IsBound(V2))
NewV2 = TopoDS::Vertex(myOldNewMap(V2));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V2);
NewV2 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV2, dmax);
myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), NewV2);
}
NewV1.Orientation(TopAbs_FORWARD);
BB.Add(NewEdge, NewV1);
NewV2.Orientation(TopAbs_REVERSED);
BB.Add(NewEdge, NewV2);
TopoDS_Vertex V1, V2;
TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
BB.UpdateVertex(V1, dmax);
BB.UpdateVertex(V2, dmax);
BB.Add(NewEdge, V1);
BB.Add(NewEdge, V2);
TopLoc_Location Loc;
BB.UpdateEdge(NewEdge, aCurveOnPlate, Surface, Loc, dmax);
//BRepLib::SameRange(NewEdge);
BRepLib::SameParameter(NewEdge, dmax, Standard_True);
FinalEdges.Append(NewEdge);
myOldNewMap.Bind(InitEdge.Oriented(TopAbs_FORWARD), NewEdge.Oriented(TopAbs_FORWARD));
myOldNewMap(InitEdge).Clear();
myOldNewMap(InitEdge).Append(NewEdge);
}
TopoDS_Wire FinalWire = WireFromList(FinalEdges);

View File

@@ -25,7 +25,7 @@
#include <BRepFill_SequenceOfEdgeFaceAndOrder.hxx>
#include <BRepFill_SequenceOfFaceAndOrder.hxx>
#include <GeomPlate_SequenceOfPointConstraint.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS_Face.hxx>
#include <Standard_Real.hxx>
@@ -207,7 +207,7 @@ private:
BRepFill_SequenceOfEdgeFaceAndOrder myConstraints;
BRepFill_SequenceOfFaceAndOrder myFreeConstraints;
GeomPlate_SequenceOfPointConstraint myPoints;
TopTools_DataMapOfShapeShape myOldNewMap;
TopTools_DataMapOfShapeListOfShape myOldNewMap;
TopTools_ListOfShape myGenerated;
TopoDS_Face myFace;
TopoDS_Face myInitFace;

View File

@@ -105,15 +105,20 @@ static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge)
Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast);
// convert its part used by edge to bspline; note that if edge curve is bspline,
// approximation or conversion made via trimmed curve is still needed -- it will copy it,
// segment as appropriate, and remove periodicity if it is periodic (deadly for approximator)
// conversion made via trimmed curve is still needed -- it will copy it, segment
// as appropriate, and remove periodicity if it is periodic (deadly for approximator)
Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast);
const Handle(Geom_Curve)& aCurveTemp = aTrimCurve; // to avoid ambiguity
GeomConvert_ApproxCurve anAppr (aCurveTemp, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (anAppr.HasResult())
aBSCurve = anAppr.Curve();
// special treatment of conic curve
if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic)))
{
const Handle(Geom_Curve)& aCurveTemp = aTrimCurve; // to avoid ambiguity
GeomConvert_ApproxCurve anAppr (aCurveTemp, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (anAppr.HasResult())
aBSCurve = anAppr.Curve();
}
// general case
if (aBSCurve.IsNull())
aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve);

View File

@@ -330,8 +330,9 @@ static Standard_Boolean SameParameter(TopoDS_Edge& E,
if (!HasPCurves(E))
{
Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
Precision::Confusion());
AppCurve.Perform(10, 10, GeomAbs_C1, Standard_True);
if (AppCurve.IsDone() && AppCurve.HasResult())
{
C3d = AppCurve.Curve3d();

View File

@@ -1347,15 +1347,13 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
}
// Eval tol2d to compute SameRange
Standard_Real UResol = Max(GAS.UResolution(theTolerance), Precision::PConfusion());
Standard_Real VResol = Max(GAS.VResolution(theTolerance), Precision::PConfusion());
Standard_Real Tol2d = Min(UResol, VResol);
Standard_Real TolSameRange = Max(GAC.Resolution(theTolerance), Precision::PConfusion());
for(Standard_Integer i = 0; i < 2; i++){
Handle(Geom2d_Curve) curPC = PC[i];
Standard_Boolean updatepc = 0;
if(curPC.IsNull()) break;
if(!SameRange){
GeomLib::SameRange(Tol2d,
GeomLib::SameRange(TolSameRange,
PC[i],GCurve->First(),GCurve->Last(),
f3d,l3d,curPC);
@@ -1375,13 +1373,17 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
if(GAC2d.GetType() == GeomAbs_BSplineCurve &&
GAC2d.Continuity() == GeomAbs_C0) {
Standard_Real UResol = GAS.UResolution(theTolerance);
Standard_Real VResol = GAS.VResolution(theTolerance);
Standard_Real TolConf2d = Min(UResol, VResol);
TolConf2d = Max(TolConf2d, Precision::PConfusion());
Handle(Geom2d_BSplineCurve) bs2d = GAC2d.BSpline();
Handle(Geom2d_BSplineCurve) bs2dsov = bs2d;
Standard_Real fC0 = bs2d->FirstParameter(), lC0 = bs2d->LastParameter();
Standard_Boolean repar = Standard_True;
gp_Pnt2d OriginPoint;
bs2d->D0(fC0, OriginPoint);
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, Tol2d);
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, TolConf2d);
isBSP = Standard_True;
if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000
@@ -1425,7 +1427,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
}
d = sqrt(d)*.1;
Tol2dbail = Max(Min(Tol2dbail,d),Tol2d);
Tol2dbail = Max(Min(Tol2dbail,d), TolConf2d);
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d,Tol2dbail);
@@ -1531,8 +1533,8 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
GAC2d.Load(bs2d,f3d,l3d);
curPC = bs2d;
if(Abs(bs2d->FirstParameter() - fC0) > Tol2d ||
Abs(bs2d->LastParameter() - lC0) > Tol2d ) {
if(Abs(bs2d->FirstParameter() - fC0) > TolSameRange ||
Abs(bs2d->LastParameter() - lC0) > TolSameRange) {
Standard_Integer NbKnots = bs2d->NbKnots();
TColStd_Array1OfReal Knots(1,NbKnots);
bs2d->Knots(Knots);
@@ -1585,7 +1587,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
//Approx_SameParameter has failed.
//Consequently, the situation might be,
//when 3D and 2D-curve do not have same-range.
GeomLib::SameRange( Tol2d, PC[i],
GeomLib::SameRange( TolSameRange, PC[i],
GCurve->First(), GCurve->Last(),
f3d,l3d,curPC);

View File

@@ -55,6 +55,7 @@
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <NCollection_Vector.hxx>
//=======================================================================
//function : Controle
@@ -174,6 +175,70 @@ BRepLib_FindSurface::BRepLib_FindSurface(const TopoDS_Shape& S,
{
Init(S,Tol,OnlyPlane,OnlyClosed);
}
namespace
{
static void fillParams (const TColStd_Array1OfReal& theKnots,
Standard_Integer theDegree,
Standard_Real theParMin,
Standard_Real theParMax,
NCollection_Vector<Standard_Real>& theParams)
{
Standard_Real aPrevPar = theParMin;
theParams.Append (aPrevPar);
Standard_Integer aNbP = Max (theDegree, 1);
for (Standard_Integer i = 1;
(i < theKnots.Length()) && (theKnots (i) < (theParMax - Precision::PConfusion())); ++i)
{
if (theKnots (i + 1) < theParMin + Precision::PConfusion())
continue;
Standard_Real aStep = (theKnots (i + 1) - theKnots (i)) / aNbP;
for (Standard_Integer k = 1; k <= aNbP ; ++k)
{
Standard_Real aPar = theKnots (i) + k * aStep;
if (aPar > theParMax - Precision::PConfusion())
break;
if (aPar > aPrevPar + Precision::PConfusion())
{
theParams.Append (aPar);
aPrevPar = aPar;
}
}
}
theParams.Append (theParMax);
}
static void fillPoints (const BRepAdaptor_Curve& theCurve,
const NCollection_Vector<Standard_Real> theParams,
TColgp_SequenceOfPnt& thePoints,
TColStd_SequenceOfReal& theWeights)
{
Standard_Real aDistPrev = 0., aDistNext;
gp_Pnt aPPrev (theCurve.Value (theParams (0))), aPNext;
for (Standard_Integer iP = 1; iP <= theParams.Length(); ++iP)
{
if (iP < theParams.Length())
{
Standard_Real aParam = theParams (iP);
aPNext = theCurve.Value (aParam);
aDistNext = aPPrev.Distance (aPNext);
}
else
aDistNext = 0.0;
thePoints.Append (aPPrev);
theWeights.Append (aDistPrev + aDistNext);
aDistPrev = aDistNext;
aPPrev = aPNext;
}
}
}
//=======================================================================
//function : Init
//purpose :
@@ -282,117 +347,57 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
}
Standard_Integer iNbPoints=0;
// Add the points with weights to the sequences
// Fill the parameters of the sampling points
NCollection_Vector<Standard_Real> aParams;
switch (c.GetType())
{
case GeomAbs_BezierCurve:
case GeomAbs_BezierCurve:
{
// Put all poles for bezier
Handle(Geom_BezierCurve) GC = c.Bezier();
Standard_Integer iNbPol = GC->NbPoles();
Standard_Real tf = GC->FirstParameter();
Standard_Real tl = GC->LastParameter();
Standard_Real r = (dfUl - dfUf) / (tl - tf);
r *= iNbPol;
if ( iNbPol < 2 || r < 1.)
// Degenerate
continue;
else
{
Handle(TColgp_HArray1OfPnt) aPoles = new (TColgp_HArray1OfPnt) (1, iNbPol);
GC->Poles(aPoles->ChangeArray1());
gp_Pnt aPolePrev = aPoles->Value(1), aPoleNext;
Standard_Real dfDistPrev = 0., dfDistNext;
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
{
if (iPol<iNbPol)
{
aPoleNext = aPoles->Value(iPol+1);
dfDistNext = aPolePrev.Distance(aPoleNext);
}
else
dfDistNext = 0.;
aPoints.Append (aPolePrev);
aWeight.Append (dfDistPrev+dfDistNext);
dfDistPrev = dfDistNext;
aPolePrev = aPoleNext;
}
}
}
break;
case GeomAbs_BSplineCurve:
{
// Put all poles for bspline
Handle(Geom_BSplineCurve) GC = c.BSpline();
Standard_Integer iNbPol = GC->NbPoles();
Standard_Real tf = GC->FirstParameter();
Standard_Real tl = GC->LastParameter();
Standard_Real r = (dfUl - dfUf) / (tl - tf);
r *= iNbPol;
if ( iNbPol < 2 || r < 1.)
// Degenerate
continue;
else
{
Handle(TColgp_HArray1OfPnt) aPoles = new (TColgp_HArray1OfPnt) (1, iNbPol);
GC->Poles(aPoles->ChangeArray1());
gp_Pnt aPolePrev = aPoles->Value(1), aPoleNext;
Standard_Real dfDistPrev = 0., dfDistNext;
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
{
if (iPol<iNbPol)
{
aPoleNext = aPoles->Value(iPol+1);
dfDistNext = aPolePrev.Distance(aPoleNext);
}
else
dfDistNext = 0.;
aPoints.Append (aPolePrev);
aWeight.Append (dfDistPrev+dfDistNext);
dfDistPrev = dfDistNext;
aPolePrev = aPoleNext;
}
}
}
break;
TColStd_Array1OfReal aKnots (1, 2);
aKnots.SetValue (1, GC->FirstParameter());
aKnots.SetValue (2, GC->LastParameter());
case GeomAbs_Line:
case GeomAbs_Circle:
case GeomAbs_Ellipse:
case GeomAbs_Hyperbola:
case GeomAbs_Parabola:
// Two points on straight segment, Four points on otheranalitical curves
iNbPoints = (c.GetType() == GeomAbs_Line ? 2 : 4);
Standard_FALLTHROUGH
default:
fillParams (aKnots, GC->Degree(), dfUf, dfUl, aParams);
break;
}
case GeomAbs_BSplineCurve:
{
Handle(Geom_BSplineCurve) GC = c.BSpline();
fillParams (GC->Knots(), GC->Degree(), dfUf, dfUl, aParams);
break;
}
case GeomAbs_Line:
{
// Two points on a straight segment
aParams.Append (dfUf);
aParams.Append (dfUl);
break;
}
case GeomAbs_Circle:
case GeomAbs_Ellipse:
case GeomAbs_Hyperbola:
case GeomAbs_Parabola:
// Four points on other analytical curves
iNbPoints = 4;
Standard_FALLTHROUGH
default:
{
// Put some points on other curves
if (iNbPoints==0)
iNbPoints = 15 + c.NbIntervals(GeomAbs_C3);
Standard_Real dfDelta = (dfUl-dfUf)/(iNbPoints-1);
Standard_Integer iPoint;
Standard_Real dfU;
gp_Pnt aPointPrev = c.Value(dfUf), aPointNext;
Standard_Real dfDistPrev = 0., dfDistNext;
for (iPoint=1, dfU=dfUf+dfDelta;
iPoint<=iNbPoints;
iPoint++, dfU+=dfDelta)
{
if (iPoint<iNbPoints)
{
aPointNext = c.Value(dfU);
dfDistNext = aPointPrev.Distance(aPointNext);
}
else
dfDistNext = 0.;
aPoints.Append (aPointPrev);
aWeight.Append (dfDistPrev+dfDistNext);
dfDistPrev = dfDistNext;
aPointPrev = aPointNext;
}
} // default:
} // switch (c.GetType()) ...
} // for (ex.Init(S,TopAbs_EDGE); ex.More() && control; ex.Next()) ...
if (iNbPoints == 0)
iNbPoints = 15 + c.NbIntervals (GeomAbs_C3);
TColStd_Array1OfReal aBounds (1, 2);
aBounds.SetValue (1, dfUf);
aBounds.SetValue (2, dfUl);
fillParams (aBounds, iNbPoints - 1, dfUf, dfUl, aParams);
}
}
// Add the points with weights to the sequences
fillPoints (c, aParams, aPoints, aWeight);
}
if (aPoints.Length() < 3) {
return;
@@ -505,79 +510,33 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
}
}
}
//
// let us be more tolerant (occ415)
Standard_Real dfDist = RealLast();
Handle(Geom_Plane) aPlane;
//
if (isSolved) {
//Plane normal can have two directions, direction is chosen
//according to direction of eigenvector
gp_Vec anN(aVec(1), aVec(2), aVec(3));
aPlane = new Geom_Plane(aBaryCenter,anN);
dfDist = Controle (aPoints, aPlane);
}
//
if (!isSolved || myTolerance < dfDist) {
gp_Pnt aFirstPnt=aPoints(1);
for (iPoint=2; iPoint<=aPoints.Length(); iPoint++) {
gp_Vec aDir(aFirstPnt,aPoints(iPoint));
Standard_Real dfSide=aDir.Magnitude();
if (dfSide<myTolerance) {
continue; // degeneration
}
for (Standard_Integer iP1=iPoint+1; iP1<=aPoints.Length(); iP1++) {
gp_Vec aCross = gp_Vec(aFirstPnt,aPoints(iP1)) ^ aDir ;
if (!isSolved)
return;
if (aCross.Magnitude() > dfSide*myTolerance) {
Handle(Geom_Plane) aPlane2 = new Geom_Plane(aBaryCenter, aCross);
Standard_Real dfDist2 = Controle (aPoints, aPlane2);
if (dfDist2 < myTolerance) {
myTolReached = dfDist2;
mySurface = aPlane2;
return;
}
if (dfDist2 < dfDist) {
dfDist = dfDist2;
aPlane = aPlane2;
}
}
}
}
}
//
//XXf
//static Standard_Real weakness = 5.0;
Standard_Real weakness = 5.0;
//XXf
if(dfDist <= myTolerance || (dfDist < myTolerance*weakness && Tol<0)) {
//XXf
//myTolReached = dfDist;
//XXt
gp_Vec aN (aVec (1), aVec (2), aVec (3));
Handle(Geom_Plane) aPlane = new Geom_Plane (aBaryCenter, aN);
myTolReached = Controle (aPoints, aPlane);
const Standard_Real aWeakness = 5.0;
if (myTolReached <= myTolerance || (Tol < 0 && myTolReached < myTolerance * aWeakness))
{
mySurface = aPlane;
//If S is wire, try to orient surface according to orientation of wire.
if(S.ShapeType() == TopAbs_WIRE && S.Closed())
if (S.ShapeType() == TopAbs_WIRE && S.Closed())
{
//
TopoDS_Wire aW = TopoDS::Wire(S);
TopoDS_Face aTmpFace = BRepLib_MakeFace(mySurface, Precision::Confusion());
TopoDS_Wire aW = TopoDS::Wire (S);
TopoDS_Face aTmpFace = BRepLib_MakeFace (mySurface, Precision::Confusion());
BRep_Builder BB;
BB.Add(aTmpFace, aW);
BRepTopAdaptor_FClass2d FClass(aTmpFace, 0.);
if ( FClass.PerformInfinitePoint() == TopAbs_IN )
BB.Add (aTmpFace, aW);
BRepTopAdaptor_FClass2d FClass (aTmpFace, 0.);
if (FClass.PerformInfinitePoint() == TopAbs_IN)
{
gp_Dir aN = aPlane->Position().Direction();
aN.Reverse();
mySurface = new Geom_Plane(aPlane->Position().Location(), aN);
gp_Dir aNorm = aPlane->Position().Direction();
aNorm.Reverse();
mySurface = new Geom_Plane (aPlane->Position().Location(), aNorm);
}
}
}
//XXf
myTolReached = dfDist;
//XXt
}
//=======================================================================
//function : Found

View File

@@ -1224,9 +1224,9 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection(
//function : addTriangle
//purpose : Add a triangle based on the given oriented edges into mesh
//=======================================================================
inline void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
const Standard_Boolean (&theEdgesOri)[3],
const Standard_Integer (&theNodesId)[3] )
void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
const Standard_Boolean (&theEdgesOri)[3],
const Standard_Integer (&theNodesId)[3] )
{
Standard_Integer aNewTriangleId =
myMeshData->AddElement(BRepMesh_Triangle(theEdgesId,
@@ -1890,7 +1890,7 @@ void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger& thePolygon,
//function : meshElementaryPolygon
//purpose : Triangulation of closed polygon containing only three edges.
//=======================================================================
inline Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
const IMeshData::SequenceOfInteger& thePolygon)
{
Standard_Integer aPolyLen = thePolygon.Length();
@@ -2434,8 +2434,9 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
p3 = GetVertex( theEdg2.FirstNode() ).Coord();
p4 = GetVertex( theEdg2.LastNode() ).Coord();
Standard_Real aIntParams[2];
return BRepMesh_GeomTool::IntSegSeg(p1, p2, p3, p4,
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt, aIntParams);
}
//=============================================================================

View File

@@ -19,191 +19,6 @@
#include <OSD_Parallel.hxx>
#include <BRepMesh_GeomTool.hxx>
namespace
{
const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
//! Functor to be used to fill segments and bounding box tree in parallel.
class SegmentsFiller
{
public:
//! Constructor.
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments,
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
: myDFace(theDFace),
myWiresSegments(theWiresSegments),
myWiresBndBoxTree(theWiresBndBoxTree)
{
myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1);
myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
}
//! Performs initialization of wire with the given index.
void operator()(const Standard_Integer theWireIndex) const
{
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
Handle(BRepMesh_FaceChecker::Segments) aSegments =
new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
{
// TODO: check 2d wire for consistency.
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
{
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
Bnd_Box2d aBox;
aBox.Add(aPnt1);
aBox.Add(aPnt2);
aBox.Enlarge(Precision::Confusion());
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
}
}
aBndBoxTreeFiller.Fill();
}
private:
SegmentsFiller (const SegmentsFiller& theOther);
void operator=(const SegmentsFiller& theOther);
private:
const IMeshData::IFaceHandle& myDFace;
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments;
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
};
//! Selector.
//! Used to identify segments with overlapped bounding boxes.
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
{
public:
//! Constructor.
BndBox2dTreeSelector(const Standard_Real theTolerance)
: myMaxLoopSize(M_PI * theTolerance * theTolerance),
mySelfSegmentIndex(-1),
myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
{
}
//! Sets working set of segments.
void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
{
mySegments = theSegments;
}
//! Resets current selector.
void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
const Standard_Integer theSelfSegmentIndex)
{
myIndices.Clear();
mySelfSegmentIndex = theSelfSegmentIndex;
mySegment = theSegment;
myBox.SetVoid();
myBox.Add(*mySegment->Point1);
myBox.Add(*mySegment->Point2);
myBox.Enlarge(Precision::Confusion());
}
//! Indicates should the given box be rejected or not.
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
{
return myBox.IsOut(theBox);
}
//! Accepts segment with the given index in case if it fits conditions.
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
{
const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
gp_Pnt2d aIntPnt;
const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
mySegment->Point1->XY(), mySegment->Point2->XY(),
aSegment.Point1->XY(), aSegment.Point2->XY(),
Standard_False, Standard_False, aIntPnt);
if (aIntStatus == BRepMesh_GeomTool::Cross)
{
const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
if (Abs(aAngle) < MaxTangentAngle)
{
return Standard_False;
}
if (mySelfSegmentIndex != -1)
{
gp_XY aPrevVec;
Standard_Real aSumS = 0.;
const gp_XY& aRefPnt = aIntPnt.Coord();
for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
{
const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
if (aCurVec.SquareModulus() < gp::Resolution())
continue;
if (aPrevVec.SquareModulus() > gp::Resolution())
aSumS += aPrevVec ^ aCurVec;
aPrevVec = aCurVec;
}
if (Abs(aSumS / 2.) < myMaxLoopSize)
{
return Standard_False;
}
}
myIndices.Append(theSegmentIndex);
return Standard_True;
}
return Standard_False;
}
//! Returns indices of intersecting segments.
const IMeshData::VectorOfInteger& Indices() const
{
return myIndices;
}
private:
Standard_Real myMaxLoopSize;
Standard_Integer mySelfSegmentIndex;
Handle(BRepMesh_FaceChecker::Segments) mySegments;
const BRepMesh_FaceChecker::Segment* mySegment;
Bnd_Box2d myBox;
IMeshData::VectorOfInteger myIndices;
};
}
//=======================================================================
//function : Constructor
//purpose :
@@ -211,8 +26,7 @@ namespace
BRepMesh_FaceChecker::BRepMesh_FaceChecker(
const IMeshData::IFaceHandle& theFace,
const IMeshTools_Parameters& theParameters)
: myDFace(theFace),
myParameters(theParameters)
: BRepMesh_SegmentedFace (theFace, theParameters)
{
}
@@ -230,50 +44,39 @@ BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
//=======================================================================
Standard_Boolean BRepMesh_FaceChecker::Perform()
{
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
collectSegments();
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
collectResult();
myWiresBndBoxTree.Nullify();
myWiresSegments.Nullify();
myWiresBndBoxTree .Nullify();
myWiresSegments .Nullify();
myWiresIntersectingEdges.Nullify();
return myIntersectingEdges->IsEmpty();
}
//=======================================================================
//function : collectSegments
//purpose :
//=======================================================================
void BRepMesh_FaceChecker::collectSegments()
{
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
}
//=======================================================================
//function : perform
//purpose :
//=======================================================================
void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
{
const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex);
const Handle(Segments)& aSegments1 = myWiresSegments ->Value (theWireIndex);
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
// TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_False);
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
{
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt);
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
aSelector.SetSegments(aSegments2);
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
{
const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
if (aBndBoxTree2->Select(aSelector) != 0)
{
@@ -287,7 +90,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
{
const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
aIntersections->Add(aSegment2.EdgePtr);
}
}

View File

@@ -16,49 +16,18 @@
#ifndef _BRepMesh_FaceChecker_HeaderFile
#define _BRepMesh_FaceChecker_HeaderFile
#include <IMeshTools_Parameters.hxx>
#include <Standard_Transient.hxx>
#include <IMeshData_Face.hxx>
#include <Standard_Type.hxx>
#include <NCollection_Shared.hxx>
#include <BRepMesh_SegmentedFace.hxx>
//! Auxiliary class checking wires of target face for self-intersections.
//! Explodes wires of discrete face on sets of segments using tessellation
//! data stored in model. Each segment is then checked for intersection with
//! other ones. All collisions are registerd and returned as result of check.
class BRepMesh_FaceChecker : public Standard_Transient
class BRepMesh_FaceChecker : public BRepMesh_SegmentedFace
{
public: //! @name mesher API
//! Identifies segment inside face.
struct Segment
{
IMeshData::IEdgePtr EdgePtr;
gp_Pnt2d* Point1; // \ Use explicit pointers to points instead of accessing
gp_Pnt2d* Point2; // / using indices.
Segment()
: Point1(NULL)
, Point2(NULL)
{
}
Segment(const IMeshData::IEdgePtr& theEdgePtr,
gp_Pnt2d* thePoint1,
gp_Pnt2d* thePoint2)
: EdgePtr(theEdgePtr)
, Point1(thePoint1)
, Point2(thePoint2)
{
}
};
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::MapOfIEdgePtr)> > ArrayOfMapOfIEdgePtr;
//! Default constructor
Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace,
const IMeshTools_Parameters& theParameters);
@@ -82,19 +51,10 @@ public: //! @name mesher API
perform(theWireIndex);
}
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient)
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, BRepMesh_SegmentedFace)
private:
//! Returns True in case if check can be performed in parallel mode.
inline Standard_Boolean isParallel() const
{
return (myParameters.InParallel && myDFace->WiresNb() > 1);
}
//! Collects face segments.
void collectSegments();
//! Collects intersecting edges.
void collectResult();
@@ -109,11 +69,6 @@ private:
private:
IMeshData::IFaceHandle myDFace;
const IMeshTools_Parameters& myParameters;
Handle(ArrayOfSegments) myWiresSegments;
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
Handle(ArrayOfMapOfIEdgePtr) myWiresIntersectingEdges;
Handle(IMeshData::MapOfIEdgePtr) myIntersectingEdges;

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