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

Compare commits

..

185 Commits

Author SHA1 Message Date
kgv
77dba7664c 0030549: Coding - split Image_AlienPixMap into several classes
Image_AlienPixMap has been split into:
- Image_AlienPixMapI defining a general interface for reading/writing images from/to external files.
- Image_FreeImage implementing interface using FreeImage library.
- Image_WinCodec implementing interface using WinCodec library.
- Image_AlienPixMap redirecting to either Image_FreeImage or Image_WinCodec.

New static method Image_AlienPixMap::SetDefaultFactory() allows configuring
an external image library implementing Image_AlienPixMapI interface
to be used by default OCCT image processing routines (texturing, image dumps, etc.).
2019-03-09 14:27:03 +03:00
kgv
88b12b7c05 0030182: Visualization, Image_AlienPixMap - support reading encoded image from memory buffer
Added two new Image_AlienPixMap::Load() methods, taking std::istream
and memory buffer (pointer, length) arguments.
This allows reading image from application memory or from file with non-zero offset.

Added Image_AlienPixMap::IsTopDownDefault() static property allowing to query rows order used by linked image library,
so that application might generate UV texture coordinates accordingly.

Added missing Release() to IWICImagingFactory instance.
2019-03-03 20:59:18 +03:00
ika
7b93ae3c5e 0030533: Data Exchange - Crash during STEP import.
Add Null checks to avoid crash during reading faces without bounds.
2019-03-03 20:58:37 +03:00
asl
6ef0d6f156 0024437: Visualization - silhouette edges based on OpenGL
Added new flag Graphic3d_AspectFillArea3d::ToDrawSilhouette() activating silhouette (outline) rendering.

The new feature can simulate fake HLR look-n-feel,
when combined with Aspect_IS_HIDDENLINE interior style (filling object with background color),
face boundary edges (with most continuity flag set to c2 or lower).

Silhouette GLSL program is very simple - it displaces model alongside vertex normal,
so that it is applicable only to smooth surfaces and closed volumes,
and produces visual artifacts at sharp corners, especially when face boundary is disabled.

OpenGl_SetOfShaderPrograms has been modified so that to reduce
dimensions of the grid of static size based on amount of program combinations.

OpenGl_PrimitiveArray no more allocates VBO resources if primitive array
is marked to be not drawn via interior style / line type / marker type.
2019-02-28 20:25:51 +03:00
nds
967d2f4f30 0030497: [REGRESSION] Mesh - wrong Poly_Polygon3D within local selection of located shape
The previous code has a condition to avoid processing the same faces if the face has a location.
The similar condition should be applied during the edges processing.
If not doing this, in the previous implementation, IMeshData_Edge instances are created for all edges(even located), but edges of faces located are not filled with curves.
As a result we had wrong local selection of edges.

Limit addition of edges to data model by ones with unique TShape and location using edges map already available in BRepMesh_ShapeVisitor.
2019-02-28 20:24:43 +03:00
pdn
4ec8ee66a0 0030356: Data Exchange - IGES model after importing into document has location issues 2019-02-28 20:23:35 +03:00
asl
0493ffd083 0029787: Visualization - Avoid in presentation edges of certain continuity class
A new flag Prs3d_Drawer::FaceBoundaryUpperContinuity() has been introduced
handled by StdPrs_ShadedShape::FillFaceBoundaries() method to exclude edges
of higher continuity class (e.g. to skip seam edges).

Draw Harness command vshowfaceboundary has been replaced by vaspects:
> vaspects -setFaceBoundaryDraw 1 -setFaceBoundaryColor RED -setFaceBoundaryType DASH.
2019-02-28 20:20:45 +03:00
Benjamin Bihler
0be7dbe183 0030448: Coding - add typo detection to derivation creation methods using Standard_NODISCARD attribute
Added macro Standard_NODISCARD equivalent to C++17 attribute [[nodiscard]] for compilers that support this.
Using Standard_NODISCARD macro for methods that create new object in gp, math, Geom, Bnd packages.
Marked equivalent operators with Standard_NODISCARD, if they are defined close to relevant methods.

Corrected code where warnings on unused result of calls to methods creating new objects are generated.
In most cases it looks like spelling errors (e.g. Normalised() instead of Normalise())
2019-02-27 19:59:07 +03:00
kgv
1c8fc6bee2 0030493: Draw, ViewerTest - minor improvement of vdisplay command
vdisplay no longer opens BREP file in case if Draw variable is not found.

Draw::Get() unused Complain argument has been removed from method definition.
Added Draw::GetExisting() and DBRep::GetExisting() commands never performing picking.
2019-02-27 19:55:32 +03:00
asl
d95f5ce102 0029810: Visualization - Tool for debugging shaders
A new tool for debugging shaders has been introduced.
The new method OpenGl_ShaderProgram::UpdateDebugDump() allows dynamically
dumping/restoring certain shader program (vertex and fragment shaders) to/from external file.

The file name is generated from the program's name with suffix ".vs" or ".fs" for shader type.
The environment variable CSF_ShadersDirectoryDump specifies the folder for dumps.

If the file does not exist (first frame), then it is automatically saved.
When the file date/time is changed in comparison with recent cached date,
then the file will be automatically loaded from external file,
thus this file can be modified in any editor.

OpenGl_ShaderManager now generates a human-readable resource ids for standard GLSL programs.

Draw Harness command vshader has been extended with arguments -list,-dump and -reload
for debugging shaders within OpenGl_Context.
2019-02-27 19:54:26 +03:00
kgv
1e756cb979 0030520: VIS - IVtkTools_ShapePicker::GetPickPosition() returns incorrect point
vmoveto and ivtkmoveto commands now print topmost picked 3D point.
2019-02-27 19:51:02 +03:00
abv
3bb61eb0fe 0029996: Porting to VC 2017: memory leak reported in visualisation
Tests for memory leaks on display / erase cycles are performed with VBO disabled to avoid false memory leaks reported on NVidia graphics
2019-02-26 15:23:18 +03:00
mnv
2a33274558 0029076: Visualization - implement element shrinking Shader
Aspect_IS_HOLLOW now an alias to Aspect_IS_EMPTY and Aspect_IS_HIDDENLINE does not implicitly enables mesh edges,
so that Graphic3d_AspectFillArea3d::SetDrawEdges() should be set independently.

OpenGl_ShaderManager now provides built-in GLSL programs for drawing mesh edges
in single pass (and on OpenGL ES which does not provide glPolygonMode()).

Graphic3d_RenderingParams::ToEnableAlphaToCoverage is now enabled by default
and properly handled at TKOpenGl level - enables coverage for Graphic3d_AlphaMode_Mask primitives.

OpenGl_PrimitiveArray now uses GLSL programs instead of glPolygonMode() by default,
which can be managed by OpenGl_Caps::usePolygonMode flag (desktop OpenGL only).
glPolygonMode() is also used as fallback regardless OpenGl_Caps::usePolygonMode flag
when GLSL programs are not supported (Geometry Shaders are required)
or stipple line style is required (not implemented within Face GLSL).

vaspects command has been extended by -setInterior -setDrawEdges -setEdgeColor -setEdgeType -setEdgeWidth
arguments replacing vsetinteriorstyle/vsetedgetype/vunsetedgetype commands.
vaspects now accepts arguments without "set" prefix.
ViewerTest::ParseColor() now parses RGBA color.

Redundant command BUC60738 has been removed.
AIS_ColorScale - fixed usage of uninitialized FillArea aspects.
2019-02-22 16:23:35 +03:00
jfa
4efe27fc4e 0030510: Application Framework - add missing NULL check within TDataStd_RealArray::ChangeArray() 2019-02-21 18:47:04 +03:00
kgv
ea298f59e4 0030384: Visualization - Won't display line with dot and dash style on Android
Fix misprint leading to double semicolon in GLSL code.
2019-02-21 18:44:37 +03:00
apn
78d5ea7a71 0030498: Warnings of building documentation
Fix warning 'Reached end of file while still insided a (nested) comment in Markdown' for old versions of doxygen
2019-02-18 14:59:32 +03:00
kgv
e084dbbc20 0030476: Visualization, Path Tracing - Adaptive Screen Sampling leads to unstable results
OpenGl_View::runPathtrace() has been extended with alternative multi-pass
Adaptive Screen Sampling mode, not relying on atomic floating point operations.
Although atomic operations on floats allows single-pass rendering,
such operations leads to instability in case of different calculation order.
Atomic float operations are also currently supported only by single GPU vendor.

Fixed GLSL compilation on Intel drivers (follow ARB_shader_image_load_store
specs rather than EXT_shader_image_load_store).

Graphic3d_RenderingParams::AdaptiveScreenSamplingAtomic option has been added
to activate 1-pass Adaptive Screen Sampling mode when supported by hardware.

vfps command has been extended with -duration argument allowing to limit command execution time.
vactivate command has been extended with -noUpdate argument.
2019-02-15 17:16:12 +03:00
kgv
66d1cdc65d 0030483: Visualization, Path Tracing - make Tile Size configurable
OpenGl_TileSampler has been refactored to better describe its logic:
- Offset image now defines tile index instead of offset to tile origin.
- Added 2D array defining the number of times to sample tile for straight-forward debugging.

Graphic3d_RenderingParams has been extended with property
RayTracingTileSize for testing various tile configurations.
Default behavior is the following:
- Target number of tiles (e.g. upper limit per frame): 256
- Tile size: 32x32.

OpenGl_View::runPathtrace() has been split into two methods per rendering stage.
OpenGl_Texture::Init() now returns FALSE immediately on 0 input dimensions.

Added Image_PixMapTypedData template class allowing to work with image data of known pixel format.
2019-02-15 17:14:19 +03:00
kgv
e607bd3e6b 0028488: VIS - fix compilation with VTK 8.2
Occurrences of removed method vtkDataArray::InsertNextTupleValue() have been replaced by InsertNextTypedTuple().
Fixed misprint in vtkTypeMacro usage for class IVtkTools_ShapeObject.
Patch #0030452 (SelectMgr_ViewerSelector::Deactivate() raises exception when called twice) has been propagated to IVtkOCC_ViewerSelector.
2019-02-15 15:52:14 +03:00
kgv
1ccc1371b9 0030486: Visualization - Rubber-band selection does not work with disabled overlap detection
SelectMgr_RectangularFrustum::Overlaps() now treats degenerated polygon as point instead of returning FALSE.
2019-02-13 17:07:17 +03:00
kgv
5ac0f98974 0030477: Visualization - crash in AIS_Manipulator::ObjectTransformation after using V3d_View::SetProj(V3d_Zpos) 2019-02-13 17:06:30 +03:00
kgv
2bda8346dc 0030488: Visualization, Ray Tracing - empty error message on GLSL program compilation
OpenGl_ShaderObject::LoadAndCompile() - added method combining Load() and Compile() with optional error logging.
OpenGl_ShaderProgram::Link() now logs failures by default.
2019-02-13 17:03:47 +03:00
kgv
92435cd0ff 0030478: Foundation Classes, NCollection_Array2 - provide Resize/Move methods consistent to NCollection_Array1 2019-02-12 18:54:34 +03:00
kgv
597fde688e 0030494: Coding Rules - eliminate declaration of OpenGl_Workspace::IsCullingEnabled() 2019-02-12 18:46:37 +03:00
abv
458ff6a680 0030129: With newest doxygen 1.8.14 generation of overview gives warnings
Doxygen configuration scripts are corrected to avoid '\n' symbols in the end of the @figure alias that caused multiple warning messages.
Other Doxygen warnings in Markdown files are eliminated.
In CMake builds the format of Doxygen warnings is set to use the style recognized by Visual Studio when compiler is MSVC.
2019-02-12 18:45:40 +03:00
nds
a7ced2a456 0030480: Visualization - Clear of Select3D_SensitiveGroup does not update internal container 2019-02-07 11:04:59 +03:00
bugmaster
ab9f6cabdc 0028936: Draw freezes while making a 3d representation
Adding testing case
2019-02-06 16:18:00 +03:00
kgv
95c882e9d4 0030329: Move BRepMesh_IncAllocator to NCollection package
NCollection_IncAllocator has been extended with optional mutex allocation (disabled by default).
2019-02-04 17:48:14 +03:00
kgv
976627e601 0030474: Visualization - fallback font is ignored for missing font alias within Font_FontMgr::FindFont() 2019-02-04 16:39:53 +03:00
kgv
d918208af6 0030469: Visualization - Draw crashes when 3D view is minimized
OpenGl_View::Redraw() - avoid rendering into window of zero size (leading to FPE and other issues).
2019-02-04 16:26:23 +03:00
kgv
98ae54f728 0030366: Coding Rules - GeometryTest_API2dCommands.cxx seems to be excess 2019-02-04 15:06:57 +03:00
kgv
c1197a1575 0030464: Visualization - unable to set sub-shape transparency using vaspects command
Added AIS_ColoredShape::SetCustomTransparency() for simple way for assigning sub-shape transparency.
2019-02-01 13:26:24 +03:00
kgv
82d23ad590 0030452: Visualization - SelectMgr_ViewerSelector::Deactivate() raises exception when called twice
Removed unused SelectMgr_SOS_Sleeping enumeration value.
SelectMgr_ViewerSelector::Deactivate() now checks activation status before updating tolerance map.
2019-01-31 20:53:34 +03:00
kgv
c29c0ad0a2 0030450: Visualization - AIS_InteractiveContext::MoveTo() never uses V3d_View::ImmediateRedraw()
AIS_InteractiveContext::MoveTo() now calls V3d_View::ImmediateRedraw() when applicable.
AIS_Trihedron::HilightOwnerWithColor() - added missing ZLayer setup.
2019-01-31 16:01:59 +03:00
gka
cf152970e2 0030405: Presentations of PMI are incorrectly scaled after change of units
Corrected search of the entity StepShape_ShapeDimensionRepresentation defining used units in the method readConnectionPoints
2019-01-24 14:24:40 +03:00
vro
a0d0f96afe 0030451: Selection mode of TPrsStd_AISPresentation attribute is restricted to one value
Two classes TDataXtd_Presentation and TPrsStd_AISPresentation were improved so that they accept a list of selection modes.
A new non-regression test is added: caf presentation N1
2019-01-23 15:33:06 +03:00
mahaidong
9c0787df75 0030429: Samples - add simple glfw 3D Viewer sample
Aspect_DisplayConnection now provides constructor wrapping existing X Display connection.
2019-01-22 15:58:32 +03:00
kgv
5b377041e3 0030439: Visualization - extend fonts search within Font_FontMgr::FindFont() on Linux
Font_FontMgr has been redesigned to:
- Store fonts in a map instead a list.
- Allow mapping multiple fonts to a single alias.
- Log informative message about usage of non-requested font (fallback).
- Register all font files within standard folders on Linux when "fonts.dir" is not found.
- Prefer specific alias ("serif") as default fallback font instead of arbitrary one in a system.

A couple of obsolete and broken font aliases have been removed;
instead, new aliases of fonts popular on Linux platform have been added.

Font_NameOfFont.hxx has been extended with more neutral aliases
"monospace", "serif", "sans-serif", "cjk" and "korean".

Font_FontAspect enumeration values have been renamed Font_FA_ -> Font_FontAspect_
with old values preserved as alias.

Font_SystemFont has been extended with a list of paths to Font_FontAspect styles,
so that entire Font Family is now defined within a single Font_SystemFont instance.
Non-resizable fonts are now ignored by Font Manager.
2019-01-21 16:15:33 +03:00
kgv
169c944c4b 0029670: Draw Harness - vtrihedron xaxis zaxis is wrong
Fixed gp_Ax2 initialization by two vectors.
Fixed -labels arguments number check.
2019-01-15 15:04:41 +03:00
osa
79b544e652 0030437: Visualization, TKV3d - add Draw command to print rendering statistics
Add new command "vstatprofiler" to manage rendering parameters and print them.
If there are some input parameters - print corresponding statistic counters values,
else - print all performance counters set previously.
2019-01-11 18:57:53 +03:00
osa
0e3025bc14 0030434: Visualization, TKV3d - add "NoUpdate" state of frustum culling optimization
Frustum culling is now managed by Graphic3d_RenderingParams::FrustumCullingState flag
and can be switched into Graphic3d_RenderingParams::FrustumCulling_NoUpdate state
useful for debugging the algorithm.

Draw Harness command vrustumculling has been replaced by vrenderparams -frustumCulling.
2019-01-11 18:57:52 +03:00
osa
30a1b24e19 0030412: Visualization, TKV3d - add presentation of camera frustum
1) Added method Graphic3d_Camera::FrustumPoints() returning corner points of camera frustum.
2) Refactored methods OpenGl_BVHTreeSelector::isFullOut(...) and OpenGl_BVHTreeSelector::CacheClipPtsProjections()
3) Changed computation algorithm of frustum planes (build them by corner points)
4) Added interactive object AIS_CameraFrustum to draw camera frustum.
5) Extended Draw command "vcamera" with option displaying camera frustum.
2019-01-11 18:57:52 +03:00
nds
25333d45ea 0030349: Coding - add usage of Standard_EXPORT for some not inline methods in Select3D 2019-01-11 18:57:51 +03:00
abv
8de8dacd02 0030430: Draw - command testgrid in parallel mode hangs if DRAW is launched without GUI
Ensure that initialization of Tcl interpretor is performed in the same thread where commands are evaluated.

Added test demo draw bug30430
2019-01-10 16:35:02 +03:00
abv
9b4243f9bf 0030377: DRAW, Windows - command executed via option -c fails on puts
When DRAW on Windows is launched with option -c, the command is now properly transferred to Tcl thread (separate thread that runs Tcl interpretor on Windows except when DRAW is run in batch mode) for execution, instead of being evaluated in the main thread.

Execution of DRAW in batch mode (option -b) is fixed by enabling proper initialization of the Tcl interpretor and replacement of backslashes in path to startup script by straight slashes on Windows in that mode.

Declaration of global variables used for communication of console command between threads is moved to Draw_Window.hxx to ensure consistency.
Function wscpy_s is used instead of memcpy to avoid possible buffer overrun.
2019-01-10 16:35:02 +03:00
kgv
0939d4cf1f 0030428: Modeling Algorithms - BRepBndLib::AddOBB() throws exception on empty Compound
Added missing Bnd_Box::IsVoid() check.
2019-01-10 16:12:13 +03:00
kgv
a345becea2 0030424: C# wrapper - implement IEnumerable interface by NCollection classes
TopExp_Explorer::Value() - added Current() alias for providing interface consistent to other OCCT Iterators.
2018-12-31 12:30:00 +03:00
ifv
80eeb3cef1 0030346: Modeling Algorithms - BRepPrimAPI_MakeRevol throws "BRepSweep_Translation::MakeEmptyVertex"
Implementation of method "IsDeleted(...)" for MakeRevol and MakePrism algorithms.

Problem (exception) occurs during history building and was caused by an attempt to obtain generated shape for subshape, which was really "deleted" by algorithm - this input subshape and its possible generated shape was not used in result.
2018-12-28 15:54:30 +03:00
kgv
39235bedc6 0030364: Visualization, TKOpenGl - allow initializing a Surface-less EGL context
OpenGl_Context::MakeCurrent()/OpenGl_Context::IsCurrent() have been modified to NOT fail
in case if myWindow is EGL_NO_SURFACE (valid off-screen rendering case within EGL).
OpenGl_GraphicDriver::InitEglContext() now finds EGL surface config in case if it has not been passed by argument.

OpenGl_Window constructor now allows wrapping an off-screen rendering surface EGL_NO_SURFACE.
However, it still creates a dummy surface eglCreatePbufferSurface() to workaround bugs in some GLES drivers (Vivante GC2000).

V3d_View::SetWindow()/V3d_View::MustBeResized()/V3d_Viewer::SetViewOn() have been modified
to avoid implicit View redraw (leading to undefined behavior/crashes in case if rendering
should be done into default FBO defined right after V3d_View initialization).
2018-12-23 20:25:14 +03:00
msv
4473e33655 0030396: Infinite recursion during ShapeFix after BRepAlgoAPI_Cut
Two test cases are added. One for Boolean operation (it is good, because BO has been fixed already), and another for fixshape operation (it causes Draw crash).
2018-12-21 19:45:20 +03:00
oan
6c27a5d993 0029964: Bad arc discretization
Added test cases.
2018-12-21 15:39:24 +03:00
nbv
4fe725a46a 0027976: Unstable work of 2d intersection algorithm for two lines
1. Test case for the issue has been created.
The problem is still reproduced on MASTER.

2. Some test cases have been moved to lowalgos/2dinter grid.
2018-12-21 15:38:03 +03:00
msv
4b97f9b15b 0030416: Incorrect implementation of the method Bnd_OBB::SquareExtent
The method Bnd_OBB::SquareExtent has been corrected.
2018-12-17 15:16:55 +03:00
kgv
3d999c6090 0030411: Data Exchange - attached model is exported as empty JT and VRML file
VrmlData_ShapeConvert::ConvertDocument() now handles reference labels within free shapes in the document.
2018-12-14 12:08:42 +03:00
kgv
7803c28d96 0030409: Data Exchange - exception during VRML file export
VrmlData_ShapeConvert::addShape() - handle case when parent node is NULL.
2018-12-14 12:07:56 +03:00
kgv
eeabb8f86a 0030413: Tests - increase counters within perf/ncollection/A1 2018-12-14 12:06:01 +03:00
skl
1d441d1ac7 0030402: Data Exchange - exported VRML file has broken location information 2018-12-13 13:34:41 +03:00
osa
2719e4f828 0030223: Visualization, TKOpenGl - frustum culling does not clip objects within perspective camera.
Fixed multiplication order of Projection and WorldView matrices
2018-12-13 13:33:42 +03:00
emv
d4db985b5e 0030395: DRAW bop: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered.
Integrating only test case for the issue as it is not reproduced any more.
2018-12-13 13:32:53 +03:00
kgv
f4d20b0086 0030400: Configuration - specify external dependencies user32 and shell32 explicitly 2018-12-11 19:16:42 +03:00
jgv
405b6fc5f9 0030391: Improvement of the method BRepOffset_Tool::EnLargeFace
Add options to set the length of enlargement for each of 4 directions.
Add restriction of enlargement in the case of singularity on the surface.
2018-12-11 19:15:54 +03:00
oan
3c7a61eae2 0029702: Foundation Classes - Introduce possibility to control parallel execution of BVH tools
Methods IsParallel() and SetParallel() have been added to BVH_Sorter, BVH_DistanceField and BVH_BuilderTransient to control parallel execution on low-level.
Fix compilation errors for old compilers without support of c++11 (std::begin, std::end)
2018-12-11 19:14:42 +03:00
oan
da555fc2ab 0029177: Foundation Classes - Adapt BVH package for use of OSD_Parallel
Explicit calls to TBB in BVH_DistanceField, BVH_LinearBuilder and BVH_RadixSorter have been replaced.
Task functors have been separated on execution and state parts for the sake of usage by OSD_Parallel.
2018-12-11 19:14:27 +03:00
emv
2ebb10988d 0030394: Modeling Algorithms - Empty result of offset operation (mode "Complete", join type - "Intersection")
The following changes have been made for improving the offset algorithm:
1. Multi-connexity support - intersection of the faces connected to the edge belonging to more than two faces is now performed.
2. Avoid intersection of the faces connected through internal edge.
3. Filling gaps (holes) in the splits of the created offset faces to increase possibility of creation of the closed volume from these splits.

Test cases for the issue.
2018-12-07 18:52:29 +03:00
emv
0c09fd3c6f 0029692: Add functionality to make the group of touching same-dimensional shapes connected
Implementation of the new class *BOPAlgo_MakeConnected* for making the group of touching same-dimensional shapes connected.
Provide the material association for the first sub-elements of the input shapes.
Provide possibility to make the connected shape periodic.

Draw commands for new algorithm:
* makeconnected - make the input shapes connected or glued, performs material associations;
* cmaterialson - returns the materials located on the requested side of a shape;
* cmakeperiodic - makes the connected shape periodic in requested directions;
* crepeatshape - repeats the periodic connected shape in requested directions requested number of times;
* cperiodictwins - returns all periodic twins for the shape;
* cclearrepetitions - clears all previous repetitions of the periodic shape, keeping the shape periodic.

Documentation & test cases for the new algorithm.
2018-12-07 18:49:58 +03:00
emv
53a73fc1d1 0029683: Add functionality to make the TopoDS_Shape periodic in 3D space
Implementation of the new class *BOPAlgo_MakePeriodic* for making the shape periodic in 3D space.
Periodicity of the shape means that the shape can be repeated in any periodic direction any number of times without creation of the new geometry or splits.
The idea of this algorithm is to make the shape look similarly on the opposite sides or on the period bounds of periodic directions.
It does not mean that the opposite sides of the shape will be mirrored. It just means the the opposite sides of the shape should be split by each other and obtain the same geometry on opposite sides.
Such approach will allow repeating the shape, i.e. translating the copy of a shape on the period, without creation of new geometry because there will be no coinciding parts of different dimension.

Draw commands for the new algorithm:
* makeperiodic - makes the shape periodic in required directions;
* repeatshape - repeats the periodic shape in requested periodic direction;
* periodictwins - returns the periodic twins for the shape;
* clearrepetitions - clears all previous repetitions of the periodic shape.

Documentation & test cases for the algorithm.
2018-12-07 18:49:44 +03:00
jgv
e9c073b866 0030363: BRepLib::SameParameter with option "forced" corrupts valid shape
Method BRepLib::SameParameter has been corrected to synchronize check of resulting tolerance with BRepCheck.
2018-12-03 15:57:36 +03:00
nbv
061cd2d841 0029149: BRepMesh produces invalid mesh on the bound of adjacent faces
1. Test case for the issue has been created. The issue is fixed by the patch #26106.

2. Since now, "tricheck" command uses edge tolerance instead of edge deflection to check cross-face-errors (set of nodes of the edge on 1st face must be equal to set of nodes of the same edge on 2nd face).
2018-11-30 18:49:27 +03:00
oan
e2fc86bbd9 0025594: Valid shape is not visualize in shading mode.
Added test case.
2018-11-30 17:28:13 +03:00
oan
1bb8ce7b7d 0025628: BRepMesh fails to mesh face with open wire, considered as correct by checkshape
Do not check status for "UnorientedWire", but check number of triangles instead.
2018-11-30 15:33:19 +03:00
oan
87036bbb70 0028719: Mesh - Display issue for special model
Clean existing triangulation before meshing.
2018-11-30 14:16:46 +03:00
ika
99524c4d24 0030273: Modeling Algorithms - Crash in postprocessing of imported shape.
Now end points of intervals calculated in GeomAdapter_Curve are not replaced by GeomAdapter_Surface.
Left bound of periodic curve less than UMin is not corrupted by LocateParameter during intervals calculating.
2018-11-30 13:39:16 +03:00
emv
44d5a096a3 0030389: Data Exchange - StlAPI_Writer does not check if the face has triangulation
When merging triangulation of the faces skip those having no triangulation.
Test case for the issue.
2018-11-30 13:38:25 +03:00
apn
7e19e96ae9 0030385: Samples - Warnings during generation of projects from .pro files
Define variables ARCH and VCVER in .pro files in qt samples.
2018-11-27 15:13:47 +03:00
abv
e05c25c123 0027620: Test perf bop boxholes crashes DRAW
Implementation of capturing of output to standard streams in DRAW (see command dlog) is revised to avoid problems with command "test" executing long test scripts:

1. Method OSD_File::Capture() is removed: on Windows it was allocating a C file descriptor for a file opened using WinAPI, and never released that descriptor (once allocated, it cannot be released separately from WinAPI file handle). Direct calls to dup/dup2 are used instead.

2. In Draw_Window.cxx the standard Tcl channels are initialized manually using corrected version of Tcl internal function. This works around a problem with Tcl channels on Windows being bound to OS device handle owned by the system which can get invalidated as result of calls to dup2() (used to capture output to standard streams).

3. Temporary file for capturing is opened once and used to store whole log, thus the need to collect log in the string stream in memory is avoided

4. Possible errors of dup() and dup2() are checked and reported

Test demo draw dlog is added

Off-topic changes:

- Test demo draw getsource is corrected for VS2017 which generates file name in lowercase
- Field myFaceBounds is initialized in constructor of the class BRepAlgo_NormalProjection to avoid undefined behavior
- Test bugs modalg_5 bug24012 is corrected to use command nproject instead of custom one, and to check propertes of the resulting shape
2018-11-23 12:18:42 +03:00
nbv
0df4bbd689 0030380: Exception while reading Step-file
Incorrect initialization of array (when upper bound is less than lower bound) has been avoided in some places.
2018-11-23 12:17:38 +03:00
kgv
a2fb712bea 0030382: Draw Harness, ViewerTest - command vdir doesn't work anymore 2018-11-22 23:14:52 +03:00
jgv
1d54b80764 0028828: Modeling Algorithms - New functionalities of BRepFilletAPI_MakeChamfer algorithm
Two new functionalities have been added in BRepFilletAPI_MakeChamfer:
- constant throat (the section of chamfer is isosceles triangle, its height is constant in all sections - this is the "throat" of the weld);
- constant throat with penetration(the section of chamfer is right-angled triangle, the first of two surfaces (where is the top of the chamfer) is virtually moved inside the solid by offset operation, the apex of the section is on the intersection curve between moved surface and second surface, right angle is at the top of the chamfer, the length of the leg from apex to top is constant - this is the "throat" of the weld).

- New abstract classes BlendFunc_GenChamfer and BlendFunc_GenChamfInv have been added;
- Class BlendFunc_Chamfer is now descended from BlendFunc_GenChamfer, class BlendFunc_ChamfInv is now descended from BlendFunc_GenChamfInv.
- New class BlendFunc_ConstThroat is descended from BlendFunc_GenChamfer, new class BlendFund_ConstThroatInv is descended from BlendFunc_GenChamfInv.
- New class BlendFunc_ConstThroatWithPenetration is descended from BlendFunc_GenChamfer, new class BlendFund_ConstThroatWithPenetrationInv is descended from BlendFunc_GenChamfInv.
- Class ChFi3d_ChBuilder has now mode of chamfer that can be ClassicChamfer, ConstThroatChamfer and ConstThroatWithPenetrationChamfer.
- Two new DRAW Test Harness commands "chamf_throat" ant "chamf_throat_with_penetration" have been added for the second mode of ChBuilder.
- The interface of DRAW Test Harness command "chamf" changed for symmetric case.
2018-11-16 19:16:05 +03:00
nbv
364c88864b 0025950: Bad performance of intersection algorithm.
1. Test case has been created.

2. Minor correction in DrawTrSurf.cxx file.
2018-11-15 17:34:44 +03:00
kgv
ce1c28b8b4 0030374: Visualization, TKOpenGl - activate texture unit Graphic3d_TextureUnit_1 after OpenGl_LayerList::renderTransparent() 2018-11-15 17:34:44 +03:00
ika
5290fb106f 0030362: Data Exchange - Writing dimensions with inches produced invalid file.
Writing dimensions into STEP files in inches not produce invalid references between STEP entities.
2018-11-15 17:34:43 +03:00
nbv
5fe14d0fac 0030354: BOP Cut doesn't modify the attached face
The reason of this problem is in wrong work of classifier algorithm (see the message ~0080992 to the issue #30354). Therefore, the algorithm of IntTools_FClass2d class has been improved. Namely, now orientation of the polygon is computed from area-criterion instead of angle. As result, some simplification of the method IntTools_FClass2d::Init(...) has been made.

<!break>

1. New constructor has been added to the class CSLib_Class2d. It allows applying TColgp_SequenceOfPnt2d.

2. DRAW-commands "addpolygonnode" and "polygonprops" have been created. They are covered by the test case "tests/geometry/2dpolygon/A1".

3. New method Poly::PolygonProperties(...) has been created. See help for detailed information.

4. New testgrid "lowalgos classifier" has been created.
2018-11-15 17:34:42 +03:00
oan
dc57476a0e 0028379: BRepMesh produces mangled mesh for a cone
Split seam edge of a cone according to the specified parameters.
Seam edge functor is called before check of triangulation consistency in order to keep face status consistent.
The cause is that split seam edge can set Outdated flag when Reused is set by another functor without reset which can lead to refusement of such face by triangulation procedure.
Fix compilation error on VS2008
2018-11-13 15:45:19 +03:00
nbv
9d083161b6 0025952: Wrong intersection curve
Test cases for the issue have been created.
2018-11-13 15:45:18 +03:00
nbv
1f17d5fbf7 0030234: BRepMesh_IncrementalMesh fail to discretize some zero-length free edges
Test case for the issue has been created.
This problem is fixed by the patch #30345.
2018-11-11 11:34:31 +03:00
nbv
0f16fd3cec 0029962: Master version of BRepMesh does not respect obvious details despite of specified deflection
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:30 +03:00
nbv
ac2ee719c0 0029685: Meshing - BRepMesh does not respect requested deflection
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:29 +03:00
nbv
9d09a1263e 0029751: Incremental mesh produces different meshes for windows and linux (debian 8)
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:27 +03:00
nbv
57d0f56b58 0027158: BRepMesh manage vertex tolerance in parametric space in improper way
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:26 +03:00
nbv
a385e6d1cd 0026889: Very poor mesh result from shape
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:25 +03:00
nbv
70bc8e4a71 0023795: Performance regression of meshing
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:24 +03:00
nbv
080fcebfca 0026928: Edges are meshed too coarsly
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-11 11:34:22 +03:00
nbv
51cf5bb604 0030345: Mesh, BRepMesh_CurveTessellator - GCPnts_TangentialDeflection throws Standard_ConstructionError
Now the algorithm GCPnts_TangentialDeflection is initialized by appropriate parameters.
2018-11-11 11:34:21 +03:00
nbv
e2f8fe449c 0025042: Cone Meshing: Missing two connecting edges.
Adding test case for the issue.
The problem has been fixed after the patch #28379.
2018-11-11 11:34:20 +03:00
nbv
42a213c67f 0023513: BRepMesh doesn't stop until out-of-memory
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-09 17:32:42 +03:00
kgv
22887d12c4 0030348: Shape Healing - ShapeFix_Wire::FixEdgeCurves() throws Standard_OutOfRange exception
Call FixClosed() instead of out-of-range FixConnected() at the last edge.
2018-11-09 17:32:41 +03:00
nbv
fb99e177e1 0027693: BRepMesh: fine edge tessellation leads to excess number of triangles along the whole U or V stripes
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-09 17:32:41 +03:00
nbv
24f355f097 0027845: BRepMesh produces invalid result on spline cavity
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-09 17:32:40 +03:00
nbv
1741292616 0026965: BRepMesh_IncrementalMesh hangs, and consumes infinite memory
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-09 17:32:40 +03:00
nbv
3f9b6e9ea4 0029205: BRepMesh skips some edges and generates invalid triangulation for the face
Adding test case for the problem.
The issue has been fixed by a patch for #26106.
2018-11-09 17:32:39 +03:00
jgv
cab49d68fc 0030186: BRepOffsetAPI_MakePipe Generated() method produces no results for the spine edges
Add method BuildHistory providing history for sub-shapes of profile and spine to BRepFill_Pipe.
2018-11-09 17:32:39 +03:00
nbv
c3ca03eb17 0030347: Mesh, BRepMesh_ModelPostProcessor - NCollection_Array1 throws Standard_RangeError
Obtaining of 3D-polygon is forbidden for not discretized edge.
2018-11-09 17:32:38 +03:00
kgv
8946be3422 0030344: Coding Rules - suppress GCC compiler warnings -Wstrict-overflow on Standard_OutOfRange_Raise_if and Standard_RangeError_Raise_if 2018-11-07 18:19:45 +03:00
abk
23babb36ec 0030243: Regression in HLR PolyAlgo in OCCT 7.1.0
The misprint leading to the problems was fixed.

"Draw" tests were created to check the fix.

"Draw" test bugs/modalg_7/bug28784 was corrected
for right changes of the results.
2018-11-07 18:17:59 +03:00
drazmyslovich
6e7791948b 0029716: Some TDF and XCAFDoc labels-related issues
1. "Descendants" closure mode is not taken into account by TDF closure tool
2. CopyTool always creates a new label at the target ignoring the relocation table
3. XCAFDoc_GraphNode throws an exception if Child of Father is not found during the unsetting
2018-11-07 18:16:51 +03:00
kgv
cf4bee7c0c 0027115: Configuration, genproj - add headers to generated MS VS projects
Header files and non-compilable source files are now included within generated VS projects.
genproj now generates DRAWEXE.rc.
2018-11-07 18:13:09 +03:00
nbv
6ff61620a3 0029329: Low performance of the General Fuse algorithm
Creation of test case.
2018-11-07 18:11:57 +03:00
kgv
c84c2ef70c 0030337: Draw Harness, ViewerTest - do not restrict vtexture to AIS_Shape 2018-11-07 18:11:56 +03:00
nbv
3c8287eb0a 0026820: bsection returns single vertex instead of curve
Test case has been created only because the problem is not reproduced on current MASTER.
2018-11-07 18:11:55 +03:00
nbv
9bc5f5850a 0021494: Intersection between cone and sphere fails
The condition (workaround), which forbid to return the intersection curve, has been removed.
2018-11-02 17:06:43 +03:00
nbv
32c408d76a 0025082: bopcommon returns different result on Windows and Linux system
Test cases have been created because the problem is not reproduced on current MASTER
2018-11-02 17:06:43 +03:00
nbv
4006ca98a2 0030322: Remove DRAW-command "mesh" as useless
In fact, the DRAW-command "mesh" is duplicate of "incmesh".

The difference is that the "mesh" creates DRAW-object MeshTest_DrawableMesh. However, this object is currently not applicable (e.g. we cannot display it).

DRAW-commands "mesh", "addshape", "smooth", "edges", "vertices", "medge", "mvertex", "triangle", "dumpvertex", "dumpedge", "dumptriangle" and "onetriangulation" have been removed.

The class MeshTest_DrawableMesh has been removed as useless.

Testgrids "mesh standard_mesh" and "mesh advanced_mesh" have been removed.
2018-11-02 17:06:42 +03:00
nbv
6933df8fe0 0030305: Strange logic in BRepMesh_Deflection::ComputeDeflection(...) method
Before the fix, angular deflection was scaled to some coefficient in the method BRepMesh_Deflection::ComputeDeflection(...). Now, angular deflection is constant.
2018-11-02 17:06:41 +03:00
nbv
46478ffe32 0030008: BRepMesh does not respect angular deflection in internal area of bspline surface
1. Check whether the mesh satisfies the required angular deflection has been amended. Namely normals (to the surface) in the ends of any not "frontier" link are made collinear (with the given angular tolerance).

2. New parameters AngleInterior and DeflectionInterior have been added in IMeshTools_Parameters structure.

3. In case of thin long faces with internal edges, add points of internal edges to control parameters using grabParamsOfInternalEdges() in order to avoid aberrations on its ends. Disable addition of parameters from boundary edges in case of BSpline surface. Deviation can be controlled through the deflection parameter.

4. Grab parameters from edges in case if there is just a single interval on BSpline surface along U and V direction.
2018-11-02 17:06:41 +03:00
oan
7bd071edb1 0026106: BRepMesh - revision of data model
Removed tight connections between data structures, auxiliary tools and algorithms in order to create extensible solution, easy for maintenance and improvements;
Code is separated on several functional units responsible for specific operation for the sake of simplification of debugging and readability;
Introduced new data structures enabling possibility to manipulate discrete model of particular entity (edge, wire, face) in order to perform computations locally instead of processing an entire model.

The workflow of updated component can be divided on six parts:
* Creation of model data structure: source TopoDS_Shape passed to algorithm is analyzed and exploded on faces and edges. For each topological entity corresponding reflection is created in data model. Note that underlying algorithms use data model as input and access it via common interface which allows user to create custom data model with necessary dependencies between particular entities;
* Discretize edges 3D & 2D curves: 3D curve as well as associated set of 2D curves of each model edge is discretized in order to create coherent skeleton used as a base in faces meshing process. In case if some edge of source shape already contains polygonal data which suites specified parameters, it is extracted from shape and stored to the model as is. Each edge is processed separately, adjacency is not taken into account;
* Heal discrete model: source TopoDS_Shape can contain problems, such as open-wire or self-intersections, introduced during design, exchange or modification of model. In addition, some problems like self-intersections can be introduced by roughly discretized edges. This stage is responsible for analysis of discrete model in order to detect and repair faced problems or refuse model’s part for further processing in case if problem cannot be solved;
* Preprocess discrete model: defines actions specific for implemented approach to be performed before meshing of faces. By default, iterates over model faces and checks consistency of existing triangulations. Cleans topological faces and its adjacent edges from polygonal data in case of inconsistency or marks face of discrete model as not required for computation;
* Discretize faces: represents core part performing mesh generation for particular face based on 2D discrete data related to processing face. Caches polygonal data associated with face’s edges in data model for further processing and stores generated mesh to TopoDS_Face;
* Postprocess discrete model: defines actions specific for implemented approach to be performed after meshing of faces. By default, stores polygonal data obtained on previous stage to TopoDS_Edge objects of source model.

Component is now spread over IMeshData, IMeshTools, BRepMeshData and BRepMesh units.

<!break>

1. Extend "tricheck" DRAW-command in order to find degenerated triangles.

2. Class BRepMesh_FastDiscret::Parameters has been declared as deprecated.

3. NURBS range splitter: do not split intervals without necessity. Intervals are split only in case if it is impossible to compute normals directly on intervals.

4. Default value of IMeshTools_Parameters::MinSize has been changed. New value is equal to 0.1*Deflection.

5. Correction of test scripts:

1) perf mesh bug27119: requested deflection is increased from 1e-6 to 1e-5 to keep reasonable performance (but still reproducing original issue)
2) bugs mesh bug26692_1, 2: make snapshot of triangulation instead of wireframe (irrelevant)

Correction in upgrade guide.
2018-11-02 17:06:40 +03:00
emv
80da8585f4 0030281: Regression to 7.2.0: Modeling Algorithms - Wrong result of CUT operation
Boolean Operations - Force the face with internal edges to be treated by the BuilderFace algorithm. It is needed for the cases when internal edges of the face go from side to side and should really split the face.
Test case for the issue.
2018-10-31 17:46:21 +03:00
jgv
9619ef4c94 0030174: ShapeUpgrade_UnifySameDomain does not unify cylindrical faces
Hotfix for issue 27271 (avoiding potential seam edges) is deleted.

Correction of test case
2018-10-30 16:06:32 +03:00
nbv
e28b8c6218 0029673: Exception while Face-Face intersection
If 2D-curves are requested in intersection result but they cannot be created (by some reason) then the full set of curves (3D and two 2D) is rejected from the intersection result.
2018-10-30 16:04:25 +03:00
nbv
a6ebe9fc7c 0028493: [Regression vs 7.0.0] Intersection algorithm produces curve with loop
1. New testgrid "lowalgos/intss" has been created. It will contain all test cases on geometrical intersection of two surfaces ("intersect" DRAW-command) and two faces ("bopcurves" DRAW-command).

2. New test case for the issue #28493 has been created because the problem is not reproduced on MASTER.

3. Test case (lowalgos/intss/bug24472) for the issue #29501 has been modified in order to check loops of the resulting intersection curves.
2018-10-30 16:04:24 +03:00
ika
100be67aa4 0030315: Data Exchange - Crash reading views during STEP import.
Add NULL check to protect against crash.
2018-10-29 11:21:20 +03:00
nbv
df1d6870c0 0024676: Wrong result done by intersection algorithm
Only test case has been created because the problem is not reproduced on the current MASTER
2018-10-26 15:48:08 +03:00
aba
f15c5f90c3 0030291: Visualization - manipulator crashes when is attached with scaling mode disabled
- in ComputeSelection() method checks are added to avoid taking triangulation of manipulator parts that are not computed
2018-10-25 19:22:15 +03:00
nbv
cdcf6fc27a 0026509: Intersection algorithm produces set of curves providing closed contour in 3D-space and not closed contour in 2D-space
Test cases have been created. No fix is needed because the described problem has not to be cause of failing of high-level OCCT-algorithms.
See the message ~80300 (issue #26509) for detail information.
2018-10-25 19:21:16 +03:00
kgv
04f0f1b046 0030270: Modeling Algorithms - BRepBndLib should provide an option for skipping infinite entities
Bnd_Box now keeps calculating of finite part of bounding box after specifying it to be Open in some direction.
The finite part can be retrieved using new method Bnd_Box::FinitePart().

Prs3d::GetDeflection() now uses Bnd_Box::FinitePart() when applying relative deflection.

Draw Harness command bounding has been extended with option -finite returing a finite part of AABB.
2018-10-24 22:53:26 +03:00
vro
253cfde728 0030214: Application Framework, TPrsStd_AISPresentation - Hidden Presentations Cannot Be Removed 2018-10-24 18:56:11 +03:00
nbv
a8b8f90dd3 0024905: Boolean cut produced invalid result
The method BOPAlgo_PaveFiller::PutClosingPaveOnCurve(...) has been improved in order to take into account extended vertex tolerance.
2018-10-24 18:55:07 +03:00
skl
5ada54fb79 0030280: Data Exchange - broken VRML output due to unescaped symbols starting comment block 2018-10-23 20:10:58 +03:00
ifv
e5826d916c 0030203: ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d array out of bound
Bug fixing: avoiding calculation if tPp == NbOfPnts
2018-10-23 20:09:55 +03:00
ifv
d8406b2f3a 0030199: Extrema Point<->Curve gives inaccurate result
Special treatment of bspline curve of first degree is implemented in Extrema_GExtPC.gxx
Test case is added
Some test cases are modified according to actual state of algorithm
2018-10-23 20:08:38 +03:00
mnv
3b4c69452b 0030119: Visualization, OpenGl_ShaderManager - implement mechanism generating in/out section of shader programs
Added functionality which generate in/out part of shaders source code from prepared list of variables.
2018-10-23 20:07:29 +03:00
kgv
87a64d53ab 0030269: Modeling Algorithms - unhandled Standard_NullObject within BRepBndLib::Add()
Added BRep_Tool::IsGeometric() check before every BRepAdaptor_Curve::Initialize().
2018-10-22 18:29:28 +03:00
osa
b49b181901 0030278: Foundation Classes - make IndexedMapNode as protected inside of NCollection_IndexedMap 2018-10-22 11:32:46 +03:00
jgv
cb6a45e318 0030204: BRepOffsetAPI_MakePipeShell crash
Add protection from type mismatch while ensuring Same Parameter on U-edges
2018-10-18 19:10:55 +03:00
szy
b34d86cb28 0030169: Application Framework - Document format version management improvement 2018-10-18 19:09:21 +03:00
kgv
90fd614536 0030248: Volume Rendering - importing volume with default parameters leads to crashes within OpenGl_Texture::Init3D() 2018-10-18 19:07:24 +03:00
ifv
5f41ce6626 0030230: An optimal bounding box of a face is too large
Bug fixing
Test case added
2018-10-18 19:06:09 +03:00
apn
20f720f11b 0030241: Test system - create option to exclude test groups from testgrid command
Add option "-exclude" to testgrid command.
It's possible to exclude groups, grids and test cases from test execution.
Add possibility to exclude subgroups from executed groups and test cases from executed subgroups\groups.
2018-10-18 12:22:29 +03:00
vro
78a8dfb9f8 0030215: Application Framework, TPrsStd_AISPresentation - Enable Lazy Presentation Updates 2018-10-17 16:35:32 +03:00
asl
da87ddc3eb 0030076: Visualization, TKV3d - API to update certain vertex attribute(s) without recomputing a presentation
Graphic3d_Buffer can be now optionally initialized as non-interleaved array of vertex attributes
and provides an interface to invalidate buffer sub-range tracked by OpenGl_PrimitiveArray.
2018-10-17 16:35:31 +03:00
kgv
34253146da 0030239: Visualization, Graphic3d_ArrayOfPrimitives - pass Graphic3d_ArrayFlags bitmask instead of dedicated Boolean flags to constructor 2018-10-17 16:35:30 +03:00
ifv
751d055356 0030194: Modeling Algorithms - Intersection points between line and torus are not found
Calling numerical solution is implemented if analytical algorithm fails
2018-10-16 10:42:37 +03:00
emv
0fdcb9c998 0030150: Modeling Algorithms - Removal of BRepAlgo_BooleanOperations and BRepAlgo_DSAccess classes
Replacing usage of BRepAlgo_DSAccess with usage of modern Boolean operations algorithms in BRepFill_Draft.
Removing BRepAlgo_BooleanOperations and BRepAlgo_DSAccess classes.

The following classes have been removed as unused:
* BRepAlgo_DataMapOfShapeBoolean
* BRepAlgo_DataMapOfShapeInterference
* BRepAlgo_EdgeConnector
* BRepAlgo_SequenceOfSequenceOfInteger
2018-10-15 20:26:25 +03:00
kgv
dc2749cfbd 0030240: Visualization, OpenGl_FrameStatsPrs - chart cannot be erased 2018-10-15 14:19:01 +03:00
kgv
c3749171b7 0030232: Visualization, StdPrs_BndBox - support Bnd_OBB in addition to Bnd_Box 2018-10-12 17:22:45 +03:00
kgv
5e30547b63 0030144: Visualization, TKOpenGl - extend OpenGl_FrameStats with frame timers 2018-10-11 19:13:23 +03:00
skl
9b9f2fe972 0030221: Data Exchange - VRML is exported with inversed normals
Added test case bugs/xde/bug30221
2018-10-11 19:12:12 +03:00
kgv
1b63268eb2 0030218: Visualization - custom selection presentation is not updated within SelectMgr_SelectableObject::UpdateTransformation()
SelectMgr_SelectableObject now assigns transformation to mySelectionPrs and myHilightPrs presentations.
Removed confusing method PrsMgr_PresentableObject::UpdateTransformation() with presentation as argument.
2018-10-10 18:50:00 +03:00
mnv
84e847557a 0030166: Visualization, TKOpenGl - add option OpenGl_Caps::glslDumpLevel dumping the source code of the shader program
Added new option -glslcode for vgldebug command with the following values:
- off   disables glsl source code dump;
- short to dump glsl source code in short format (except common declarations);
- full  to dump glsl source code in full format.
2018-10-10 18:48:37 +03:00
emv
dce5b3eb0c 0030198: Regression to 7.1.0: BRepAlgoAPI_Fuse unlimited memory usage
When refining the mesh to achieve required deflection (IntPolyh_Triangle::MultipleMiddleRefinement) limit the number of new triangles to avoid infinite loop.
Test case for the issue.
2018-10-10 18:47:18 +03:00
nbv
f67d7efd4e 0030207: ChFi3d_KParticular stack-use-after-scope
References to temporary objects have been eliminated.
2018-10-10 18:47:17 +03:00
nbv
dcd768a49a 0030202: IntPatch_WLineTool::JoinWLines array out of bounds
The main idea of the fix is that the creation of WLine with one point is forbidden.
2018-10-10 18:47:17 +03:00
ifv
dcf0889fc2 0030133: Modeling Data - Crash during visualization of invalid part
Control of number of recursive calls is implemented to avoid stack overflow.
2018-10-10 18:47:16 +03:00
mnv
6997ff1c88 0029020: Visualization, V3d_View - workaround image dump issue on Intel OpenGL driver
Implemented workaround for dump images with width >= 5462 pix on Intel OpenGl driver.
Changes according to OpenGl_Context::myVendor field in lowercase.
2018-10-05 15:31:38 +03:00
nbv
521648ce02 0030176: Modeling Algorithms - Infinite loop in IntWalk_PWalking::Perform()
Currently resetting of counter LevelOfIterWithoutAppend is enabled only if additional iterations have taken some positive effect.
2018-10-04 18:09:44 +03:00
ika
87efa821fa 0030189: Data Exchange - Wrong export to STEP of located root.
Now roots-references in XCAF Document can be exported to STEP without losing structure of assembly/sharing/metadata of this root. New auxiliary root assembly with each root-reference is created to save all necessary data.
2018-10-04 17:57:13 +03:00
emv
13c0e40223 0030145: Modeling Algorithms - Boolean Operations on open solids
Provide possibility to perform Boolean operations on open solids.

Implementation of the new method *BOPAlgo_Builder::BuildBOP* performing the construction of the result shape for the given type of Boolean operation.
This approach does not rely on the splits of solid to be correct and looks for the faces with necessary state relatively opposite solids to build the result solid.
The call to this method is performed from BOP algorithm in case there were open solids in the arguments.

Implementation of the draw command *buildbop* performing a call to the method above.
2018-10-03 19:21:14 +03:00
emv
60b1a085c7 0030154: [REGRESSION] Modeling Algorithms - Boolean Operation on planar geometry hangs inside BRepLib::FindValidRange()
Do not allow the precision with which the valid range is found to be less than the epsilon of the max parameter of the edge's range.
Test cases for the issue.
2018-09-28 11:07:35 +03:00
skl
a3506de770 0030115: Implementation of import from XCAF to VRML. 2018-09-27 19:28:32 +03:00
mnv
eaac086605 0030153: Visualization, TKOpenGl - AIS_ColoredShape::SynchronizeAspects() doesn't update all aspects
AIS_InteractiveObject::SynchronizeAspects() now propagates event
to OpenGl_Group::SynchronizeAspects() which properly handles
all aspects defined within the group.
2018-09-26 12:19:07 +03:00
asl
f2eaecb217 0030156: Visualization, TKV3d - Triangles outside of selection volume are selected
The addition of elements to map is put under correct condition that element overlaps with selection volume
2018-09-26 12:09:52 +03:00
kgv
72a2da560f 0030157: Draw Harness - xwd image dump should not be limited by desktop size within batch testing
DrawWindow now uses SWP_NOSENDCHANGING flag within batch mode to ensure
that created window is not clipped in size by desktop dimensions.
2018-09-24 17:57:45 +03:00
jgv
a922aab52c 0028949: BRepOffsetAPI_MakePipe Generated() method produces no result for spine edges
Add history for subshapes of spine: edges and vertices. Each edge of spine generates a shell. Each vertex of spine generates a set of edges and, possibly, faces (in the case of Round Corner).
2018-09-24 17:54:57 +03:00
kgv
4ba5491a50 0030146: Visualization - exception during attempt to display Edge without geometry
StdPrs_ToolRFace no skips curves with NULL curves.
Code has been cleaned up from duplicated checks, redundant casts
and dummy Adaptor2d_Curve2dPtr typedef.

StdSelect_BRepSelectionTool::GetSensitiveForFace() now catches
Standard_NullObject exception to skip invalid Edges.
2018-09-22 17:48:53 +03:00
mnv
c39bb31bac 0030136: Visualization, TKOpenGl - Graphic3d_TOSM_FACET does not work on mobile devices
Added new type of graphic3d limit Graphic3d_TypeOfLimit_HasFlatShading.
Added workaround for unexpected behaviour of mobile devices with Adreno GPU.
Added new complex flag hasFlatShading to OpenGl_Context for indicating support of flat shading.
2018-09-20 17:08:47 +03:00
vro
39effd08e5 0030142: Application Framework, TPrsStd_AISPresentation - Hidden Presentations Are Computed During Document Retrieval 2018-09-19 11:58:33 +03:00
nbv
7e425ba7b0 0030140: Modeling Algorithms - Access Null Pointer
The array TabP has been allocated correctly.
2018-09-19 11:58:32 +03:00
kgv
b8f7f6081f 0030143: Foundation Classes - provide operator[] alias for NCollection_Array1, NCollection_Vector 2018-09-17 13:16:42 +03:00
kgv
0de16e296a 0030135: Visualization, TKOpenGl - frame statistics do not include information about instanced structures
OpenGl_FrameStats now takes into account OpenGl_Structure::InstancedStructure().
OpenGl_View::renderStructs() - fixed resetting non-culled structure counters.
2018-09-14 15:51:52 +03:00
abv
6b1800cb76 0030130: Coding Rules - MSVC 2017 gives warnings about using of std::fpos::seekpos() within RWStl
Use of deprecated method std::fpos::seekpos() is avoided with MSVC 11 (Visual Studio 2012) and above.
2018-09-13 20:45:08 +03:00
osa
d0bcf7aa9b 0030131: Foundation Classes - support of Linear builder for 2D BVH trees
BVH_LinearBuilder and BVH_RadixSorter now accept N==2.
NCollection_Vec2/3/4 - added missing division by vec operators.
2018-09-13 20:42:21 +03:00
kgv
7604a15365 0029988: AIS_Shape - SetWidth() and SetColor() has no effect for FaceBoundary
AIS_Shape SetWidth and SetColor methods now propagate modifications to FaceBoundary aspect.
2018-09-11 20:39:21 +03:00
kgv
c60ec7f521 0030118: Draw Harness - extend vcomputehlr command with HLR algo type
vcomputehlr has been extended with -algoType argument
and sets result as DBRep shape in addition to displaying AIS_Shape.
2018-09-11 20:30:48 +03:00
emv
241a61330a 0030092: Modeling Algorithms - Invalid result of Section operation
The following improvements have been made in Boolean operations algorithm in order to fix the problem:
1. Initialization of the pave blocks which vertices have acquired the SD ones.
2. Removing from Data Structure the small edges having the same vertices on both ends (either initially or acquired).
3. Avoid adding empty SD connections when one vertex points to itself.

Test case for the issue.
2018-09-11 20:24:47 +03:00
apn
798a95ed9b 0029986: Configuration - environment scripts generated by CMake on Linux do not allow starting DRAW from build folder
Correct launching custom.sh in env.sh.in.
Correct definition of FFMPEG_DIR in custom.build.bat/sh.in and generation of custom_*.sh (variables CSF_OCCTBinPath and CSF_OCCTLibPath are not empty on the first run)
2018-09-11 20:08:12 +03:00
abv
5fecc4953b 0030091: Configuration - allow cross-compilation from Linux (case sensitive filesystem) to x86_64-w64-mingw32
Names of Windows header files are corrected to be lower case to match their actual names on Windows (except Windows.h) and MinGW.
Files COMMANDWINDOW.h and MAINWINDOW.h in Draw package are renamed to CamelCase according to names of corresponding CXX files.
2018-09-07 13:11:33 +03:00
mnv
112139f00a 0030026: Configuration, CMake - not clear description of some fields
Updated description for 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 and 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build fields.
2018-09-05 18:54:48 +03:00
emv
82d3cd0b0a 0030094: Modeling Algorithms - Defeaturing does not work on the attached shape due to incorrect extension of the torus
BRepLib::ExtendFace method when working with analytical and periodic faces now takes into account the possible closeness of the result face.
Test cases for the issue.
2018-09-04 19:24:43 +03:00
emv
83f7dbeb62 0030100: Modeling Algorithms - ShapeUpgrade_UnifySameDomain is unable to unify faces based on the same toroidal surface
When performing intersection of toroidal faces check first if they are based on the same surface.
Test cases for the issue.
2018-09-04 19:24:42 +03:00
nbv
98974dccef 0029972: Intersection curve has a weird gap in the middle of it
1. The condition of WLine breaking (in IntWalk_IWalking algorithm) has become more independent of the input tolerance.

2. Currently the algorithm of IntPatch_Points of WLine processing depends on the algorithm of obtaining the WLine.

3. The methods IntSurf_LineOn2S::Add(...) and IntSurf_LineOn2S::SetUV(...) have become not inline (see the message ~0077431 in the issue #29866).
2018-09-03 17:05:14 +03:00
gka
06a505ba53 0030087: Invalid result of the translation of the assembly when relating and related products are mixed in the SRR entity
Detection of specific case of error in the definition of transformation matrix describing position of the component within assembly, when it has Axis Placements swapped, is corrected to handle the case when one of these Axis Placements is contained in both Shape Representations (of the assembly and its component).
This allows the problematic STEP file to be translated correctly.

Added test bugs step bug30087
2018-09-03 15:48:41 +03:00
mnv
1ad3bc4c00 0030102: Visualization, TKOpenGl - Graphic3d_TOSM_FACET shading is incorrect in some casesn
gl_FrontFacing is now considered within Normal computation.
2018-09-03 15:46:20 +03:00
apn
93808a4a9c 0030093: Test system - Incorrect parsing of the regular expression
Add "\-" to regular expression (which contained only literal, numeric and underscore character).
2018-09-03 15:44:41 +03:00
emv
0e48692e82 0030090: Modeling Algorithms - BRepLib::FindValidRange does not find valid range for the edge
BRepLib::FindValidRange - check each sampling point to be out of tolerance sphere of the vertex.
Test case for the issue.
2018-09-01 11:10:22 +03:00
emv
56062e13f2 0027928: BOP common produces empty compound
BOPTools_AlgoTools::ComputeState - increase the chance of correct classification of the face relatively solid by classifying the point located inside that face instead of the point taken near the edge of that face.
Test case for the issue.
2018-09-01 11:07:05 +03:00
nbv
7eb3580b79 0030082: Intersection algorithm returns curve with big tolerance value
The fix inserts new points at the end of the WLine in case when the direction of the intersection curve is significantly changed.
2018-09-01 11:06:55 +03:00
1446 changed files with 56857 additions and 25474 deletions

View File

@@ -63,7 +63,7 @@ set (BUILD_RESOURCES OFF CACHE BOOL "${BUILD_RESOURCES_DESCR}")
# single-configuration generator
set (SINGLE_GENERATOR OFF)
if (CMAKE_BUILD_TYPE)
if (DEFINED CMAKE_BUILD_TYPE)
set (SINGLE_GENERATOR ON)
endif()
@@ -899,11 +899,19 @@ if (BUILD_SAMPLES_MFC OR BUILD_SAMPLES_QT)
OCCT_COPY_FILE_OR_DIR ("adm/templates/sample.${SCRIPT_EXT}" "${CMAKE_BINARY_DIR}")
endif()
# env script for draw in building environment
OCCT_CONFIGURE ("adm/templates/env.${SCRIPT_EXT}.in" "env.${SCRIPT_EXT}")
# install env script
install (FILES "${CMAKE_BINARY_DIR}/env.${SCRIPT_EXT}" DESTINATION "${INSTALL_DIR_SCRIPT}")
if (WIN32)
# env script for draw in building environment
OCCT_CONFIGURE ("adm/templates/env.${SCRIPT_EXT}.in" "env.${SCRIPT_EXT}")
# install env script
install (FILES "${CMAKE_BINARY_DIR}/env.${SCRIPT_EXT}" DESTINATION "${INSTALL_DIR_SCRIPT}")
else()
set (SUB_ENV_NAME "env.${SCRIPT_EXT}")
set (SUB_ENV_BUILD_NAME "env.install.${SCRIPT_EXT}")
# install env script
OCCT_CONFIGURE_AND_INSTALL ("adm/templates/env.install.${SCRIPT_EXT}.in" "${SUB_ENV_BUILD_NAME}" "${SUB_ENV_NAME}" "${INSTALL_DIR_SCRIPT}")
# env script for draw in building environment
OCCT_CONFIGURE ("adm/templates/env.build.${SCRIPT_EXT}.in" "env.${SCRIPT_EXT}")
endif()
# copy DrawAppliInit from OCCT source to build directory
if (NOT EXISTS "${CMAKE_BINARY_DIR}/DrawAppliInit")

View File

@@ -105,6 +105,7 @@ n BRepIntCurveSurface
n BRepLib
n BRepMAT2d
n BRepMesh
n BRepMeshData
n BRepOffset
n BRepOffsetAPI
n BRepPrim
@@ -141,6 +142,8 @@ n HLRTopoBRep
n HLRAppli
n Hatch
n HatchGen
n IMeshData
n IMeshTools
n IntCurve
n IntCurveSurface
n IntCurvesFace

View File

@@ -37,6 +37,10 @@ foreach (LIBRARY_NAME ${CSF_FFmpeg})
set (3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME} "" CACHE PATH "The directory containing FFmpeg framework (${LIBRARY_NAME})")
endif()
if (NOT DEFINED 3RDPARTY_FFMPEG_LIBRARY_DIR)
set (3RDPARTY_FFMPEG_LIBRARY_DIR "" CACHE PATH "The directory containing FFmpeg libraries")
endif()
if (WIN32)
if (NOT DEFINED 3RDPARTY_FFMPEG_DLL_${LIBRARY_NAME} OR NOT 3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME} OR NOT EXISTS "${3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME}}")
set (3RDPARTY_FFMPEG_DLL_${LIBRARY_NAME} "" CACHE FILEPATH "FFmpeg shared libraries (${LIBRARY_NAME})" FORCE)
@@ -47,6 +51,9 @@ foreach (LIBRARY_NAME ${CSF_FFmpeg})
if (NOT DEFINED 3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME})
set (3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME} "" CACHE PATH "The directory containing FFmpeg shared libraries (${LIBRARY_NAME})")
endif()
if (NOT DEFINED 3RDPARTY_FFMPEG_DLL_DIR)
set (3RDPARTY_FFMPEG_DLL_DIR "" CACHE PATH "The directory containing FFmpeg shared libraries")
endif()
endif()
# check 3RDPARTY_${PRODUCT_NAME}_ paths for consistency with specified 3RDPARTY_${PRODUCT_NAME}_DIR
@@ -56,6 +63,7 @@ foreach (LIBRARY_NAME ${CSF_FFmpeg})
if (3RDPARTY_FFMPEG_LIBRARY_${LIBRARY_NAME} AND EXISTS "${3RDPARTY_FFMPEG_LIBRARY_${LIBRARY_NAME}}")
get_filename_component (3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME} "${3RDPARTY_FFMPEG_LIBRARY_${LIBRARY_NAME}}" PATH)
set (3RDPARTY_FFMPEG_LIBRARY_DIR "${3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME}}" CACHE PATH "The directory containing FFmpeg libraries" FORCE)
set (3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME} "${3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME}}" CACHE PATH "The directory containing FFmpeg library (${LIBRARY_NAME})" FORCE)
else()
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_LIBRARY_DIR_${LIBRARY_NAME} PATH "The directory containing FFmpeg library (${LIBRARY_NAME})")
@@ -66,6 +74,7 @@ foreach (LIBRARY_NAME ${CSF_FFmpeg})
if (3RDPARTY_FFMPEG_DLL_${LIBRARY_NAME} AND EXISTS "${3RDPARTY_FFMPEG_DLL_${LIBRARY_NAME}}")
get_filename_component (3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME} "${3RDPARTY_FFMPEG_DLL_${LIBRARY_NAME}}" PATH)
set (3RDPARTY_FFMPEG_DLL_DIR "${3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME}}" CACHE PATH "The directory containing FFmpeg shared libraries" FORCE)
set (3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME} "${3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME}}" CACHE PATH "The directory containing FFmpeg shared library (${LIBRARY_NAME})" FORCE)
else()
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_DLL_DIR_${LIBRARY_NAME} PATH "The directory containing FFmpeg shared library (${LIBRARY_NAME})")

View File

@@ -61,8 +61,8 @@ endif()
# check 3RDPARTY_FREETYPE_ paths for consistency with specified 3RDPARTY_FREETYPE_DIR
if (3RDPARTY_FREETYPE_DIR AND EXISTS "${3RDPARTY_FREETYPE_DIR}")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build FILEPATH "the path to ft2build.h")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 FILEPATH "the path to ftheader.h")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build FILEPATH "The directory containing ft2build.h header")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 FILEPATH "The directory containing ftheader.h header")
if (BUILD_SHARED_LIBS)
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR 3RDPARTY_FREETYPE_LIBRARY FILEPATH "the path to freetype library")
@@ -119,8 +119,8 @@ if (IS_BUILTIN_SEARCH_REQUIRED)
# check the found paths for consistency with specified 3RDPARTY_FREETYPE_DIR
if (3RDPARTY_FREETYPE_DIR AND EXISTS "${3RDPARTY_FREETYPE_DIR}")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR FREETYPE_INCLUDE_DIR_ft2build FILEPATH "the path to ft2build.h")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR FREETYPE_INCLUDE_DIR_freetype2 FILEPATH "the path to ftheader.h")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR FREETYPE_INCLUDE_DIR_ft2build FILEPATH "The directory containing ft2build.h header")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR FREETYPE_INCLUDE_DIR_freetype2 FILEPATH "The directory containing ftheader.h header")
if (BUILD_SHARED_LIBS)
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FREETYPE_DIR FREETYPE_LIBRARY FILEPATH "freetype library")
endif()
@@ -129,13 +129,13 @@ if (IS_BUILTIN_SEARCH_REQUIRED)
# assign the found paths to corresponding 3RDPARTY_FREETYPE_ variables
if (NOT 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build OR NOT EXISTS "${3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build}")
if (FREETYPE_INCLUDE_DIR_ft2build AND EXISTS "${FREETYPE_INCLUDE_DIR_ft2build}")
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "${FREETYPE_INCLUDE_DIR_ft2build}" CACHE FILEPATH "the path to ft2build.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "${FREETYPE_INCLUDE_DIR_ft2build}" CACHE FILEPATH "The directory containing ft2build.h header" FORCE)
endif()
endif()
if (NOT 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 OR NOT EXISTS "${3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2}")
if (FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}")
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "${FREETYPE_INCLUDE_DIR_freetype2}" CACHE FILEPATH "the path to ftheader.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "${FREETYPE_INCLUDE_DIR_freetype2}" CACHE FILEPATH "The directory containing ftheader.h header" FORCE)
endif()
endif()
@@ -162,7 +162,7 @@ if (NOT 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build OR NOT EXISTS "${3RDPARTY_FREETYP
set (FT2BUILD_NAMES ft2build.h config/ft2build.h freetype/config/ft2build.h)
# set 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build as notfound, otherwise find_library can't assign a new value to 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build-NOTFOUND" CACHE FILEPATH "the path to ft2build.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build-NOTFOUND" CACHE FILEPATH "The directory containing ft2build.h header" FORCE)
# cmake (version < 3.0) doesn't find ft2build.h of freetype (version is >= 2.5.1)
# do search taking into account freetype structure of 2.5.1 version
@@ -185,7 +185,7 @@ if (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build AND EXISTS "${3RDPARTY_FREETYPE_INCLU
else()
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "" CACHE FILEPATH "the path to ft2build.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build "" CACHE FILEPATH "The directory containing ft2build.h header" FORCE)
endif()
# ftheader.h
@@ -193,7 +193,7 @@ if (NOT 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 OR NOT EXISTS "${3RDPARTY_FREETY
set (FTHEADER_NAMES ftheader.h config/ftheader.h freetype/config/ftheader.h)
# set 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 as notfound, otherwise find_library can't assign a new value to 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2-NOTFOUND" CACHE FILEPATH "the path to ftheader.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2-NOTFOUND" CACHE FILEPATH "The directory containing ftheader.h header" FORCE)
if (3RDPARTY_FREETYPE_DIR AND EXISTS "${3RDPARTY_FREETYPE_DIR}")
find_path (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 NAMES ${FTHEADER_NAMES}
@@ -214,7 +214,7 @@ if (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${3RDPARTY_FREETYPE_INCL
else()
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "" CACHE FILEPATH "the path to ftheader.h" FORCE)
set (3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2 "" CACHE FILEPATH "The directory containing ftheader.h header" FORCE)
endif()
# freetype library

View File

@@ -62,8 +62,9 @@ if (WIN32)
set (CSF_advapi32 "advapi32.lib")
set (CSF_gdi32 "gdi32.lib")
set (CSF_user32 "user32.lib")
set (CSF_shell32 "shell32.lib")
set (CSF_wsock32 "wsock32.lib")
set (CSF_psapi "Psapi.lib")
set (CSF_psapi "psapi.lib")
set (CSF_d3d9 "D3D9.lib")
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsStore" OR USE_GLES2)
set (CSF_OpenGlLibs "libEGL libGLESv2")

View File

@@ -1263,12 +1263,16 @@ proc wokUtils:FILES:FileToString { fin } {
# List extensions of compilable files in OCCT
proc osutils:compilable {thePlatform} {
if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } {
return [list .c .cxx .cpp .mm]
}
if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } { return [list .c .cxx .cpp .mm] }
return [list .c .cxx .cpp]
}
# List extensions of header file in OCCT
proc osutils:fileExtensionsHeaders {thePlatform} {
if { "$thePlatform" == "mac" || "$thePlatform" == "ios" } { return [list .h .hxx .hpp .lxx .pxx .gxx ] }
return [list .h .hxx .hpp .lxx .pxx .gxx .mm ]
}
proc osutils:commonUsedTK { theToolKit } {
set anUsedToolKits [list]
set aDepToolkits [LibToLink $theToolKit]
@@ -1341,6 +1345,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
set aLibsMap(CSF_advapi32) "advapi32"
set aLibsMap(CSF_gdi32) "gdi32"
set aLibsMap(CSF_user32) "user32 comdlg32"
set aLibsMap(CSF_shell32) "shell32"
set aLibsMap(CSF_opengl32) "opengl32"
set aLibsMap(CSF_wsock32) "wsock32"
set aLibsMap(CSF_netapi32) "netapi32"
@@ -1465,8 +1470,7 @@ proc osutils:tk:units { tkloc } {
}
proc osutils:justwnt { listloc } {
# ImageUtility is required for support for old (<6.5.4) versions of OCCT
set goaway [list Xdps Xw ImageUtility WOKUnix]
set goaway [list Xw]
return [osutils:juststation $goaway $listloc]
}
@@ -1556,31 +1560,28 @@ proc wokUtils:FILES:wtail { f n } {
}
# Generate entry for one source file in Visual Studio 10 project file
proc osutils:vcxproj:file { file params } {
append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
if { $params != "" } {
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
}
if { $params != "" } {
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
}
if { $params != "" } {
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
}
if { $params != "" } {
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">[string trim ${params}] %(AdditionalOptions)</AdditionalOptions>\n"
proc osutils:vcxproj:cxxfile { theFile theParams } {
if { $theParams == "" } {
return " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\" />\n"
}
set aParams [string trim ${theParams}]
append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\">\n"
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|Win32\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Debug|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
append text " <AdditionalOptions Condition=\"\'\$(Configuration)|\$(Platform)\'==\'Release|x64\'\">${aParams} %(AdditionalOptions)</AdditionalOptions>\n"
append text " </ClCompile>\n"
return $text
}
# Generate entry for one header file in Visual Studio 10 project file
proc osutils:vcxproj:hxxfile { theFile } { return " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $theFile 3]]\" />\n" }
# Generate Visual Studio 2010 project filters file
proc osutils:vcxproj:filters { dir proj theFilesMap } {
upvar $theFilesMap aFilesMap
proc osutils:vcxproj:filters { dir proj theCxxFilesMap theHxxFilesMap } {
upvar $theCxxFilesMap aCxxFilesMap
upvar $theHxxFilesMap aHxxFilesMap
# header
append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
@@ -1591,60 +1592,25 @@ proc osutils:vcxproj:filters { dir proj theFilesMap } {
append text " <Filter Include=\"Source files\">\n"
append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
append text " </Filter>\n"
foreach unit $aFilesMap(units) {
append text " <Filter Include=\"Source files\\${unit}\">\n"
append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
append text " </Filter>\n"
}
append text " </ItemGroup>\n"
# list of files
append text " <ItemGroup>\n"
foreach unit $aFilesMap(units) {
foreach file $aFilesMap($unit) {
append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
append text " <Filter>Source files\\${unit}</Filter>\n"
append text " </ClCompile>\n"
}
}
append text " </ItemGroup>\n"
# end
append text "</Project>"
# write file
set fp [open [set fvcproj [file join $dir ${proj}.vcxproj.filters]] w]
fconfigure $fp -translation crlf
puts $fp $text
close $fp
return ${proj}.vcxproj.filters
}
# Generate Visual Studio 2011 project filters file
proc osutils:vcx1proj:filters { dir proj theFilesMap } {
upvar $theFilesMap aFilesMap
# header
append text "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
append text "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
# list of "filters" (units)
append text " <ItemGroup>\n"
append text " <Filter Include=\"Source files\">\n"
append text " <Filter Include=\"Header files\">\n"
append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
append text " </Filter>\n"
foreach unit $aFilesMap(units) {
foreach unit $aCxxFilesMap(units) {
append text " <Filter Include=\"Source files\\${unit}\">\n"
append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
append text " </Filter>\n"
}
foreach unit $aHxxFilesMap(units) {
append text " <Filter Include=\"Header files\\${unit}\">\n"
append text " <UniqueIdentifier>[OS:genGUID]</UniqueIdentifier>\n"
append text " </Filter>\n"
}
append text " </ItemGroup>\n"
# list of files
# list of cxx files
append text " <ItemGroup>\n"
foreach unit $aFilesMap(units) {
foreach file $aFilesMap($unit) {
foreach unit $aCxxFilesMap(units) {
foreach file $aCxxFilesMap($unit) {
append text " <ClCompile Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
append text " <Filter>Source files\\${unit}</Filter>\n"
append text " </ClCompile>\n"
@@ -1652,8 +1618,19 @@ proc osutils:vcx1proj:filters { dir proj theFilesMap } {
}
append text " </ItemGroup>\n"
# list of hxx files
append text " <ItemGroup>\n"
append text " <ResourceCompile Include=\"${proj}.rc\" />"
foreach unit $aHxxFilesMap(units) {
foreach file $aHxxFilesMap($unit) {
append text " <ClInclude Include=\"..\\..\\..\\[wokUtils:EASY:bs1 [wokUtils:FILES:wtail $file 3]]\">\n"
append text " <Filter>Header files\\${unit}</Filter>\n"
append text " </ClInclude>\n"
}
}
append text " </ItemGroup>\n"
append text " <ItemGroup>\n"
append text " <ResourceCompile Include=\"${proj}.rc\" />\n"
append text " </ItemGroup>\n"
# end
@@ -1726,9 +1703,9 @@ proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
set anIncPaths "..\\..\\..\\inc"
# set aTKDefines ""
set aFilesSection ""
set aVcFilesX(units) ""
set aVcFilesCxx(units) ""
set aVcFilesHxx(units) ""
set listloc [osutils:tk:units $theToolKit]
set resultloc [osutils:justwnt $listloc]
if [array exists written] { unset written }
#puts "\t1 [wokparam -v %CMPLRS_CXX_Options [w_info -f]] father"
#puts "\t2 [wokparam -v %CMPLRS_CXX_Options] branch"
@@ -1737,9 +1714,10 @@ proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
set fxloparamfcxx [lindex [osutils:intersect3 [_get_options wnt cmplrs_cxx f] [_get_options wnt cmplrs_cxx b]] 2]
set fxloparamfc [lindex [osutils:intersect3 [_get_options wnt cmplrs_c f] [_get_options wnt cmplrs_c b]] 2]
set fxloparam ""
foreach fxlo $resultloc {
foreach fxlo $listloc {
set xlo $fxlo
set aSrcFiles [osutils:tk:files $xlo wnt]
set aSrcFiles [osutils:tk:cxxfiles $xlo wnt]
set aHxxFiles [osutils:tk:hxxfiles $xlo wnt]
set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx $fxlo]
if {$fxlo_cmplrs_options_cxx == ""} {
set fxlo_cmplrs_options_cxx [_get_options wnt cmplrs_cxx b]
@@ -1768,12 +1746,22 @@ proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
foreach aSrcFile [lsort $aSrcFiles] {
if { ![info exists written([file tail $aSrcFile])] } {
set written([file tail $aSrcFile]) 1
append aFilesSection [osutils:vcxproj:file $aSrcFile $needparam]
append aFilesSection [osutils:vcxproj:cxxfile $aSrcFile $needparam]
} else {
puts "Warning : in vcproj more than one occurences for [file tail $aSrcFile]"
}
if { ! [info exists aVcFilesX($xlo)] } { lappend aVcFilesX(units) $xlo }
lappend aVcFilesX($xlo) $aSrcFile
if { ! [info exists aVcFilesCxx($xlo)] } { lappend aVcFilesCxx(units) $xlo }
lappend aVcFilesCxx($xlo) $aSrcFile
}
foreach aHxxFile [lsort $aHxxFiles] {
if { ![info exists written([file tail $aHxxFile])] } {
set written([file tail $aHxxFile]) 1
append aFilesSection [osutils:vcxproj:hxxfile $aHxxFile]
} else {
puts "Warning : in vcproj more than one occurences for [file tail $aHxxFile]"
}
if { ! [info exists aVcFilesHxx($xlo)] } { lappend aVcFilesHxx(units) $xlo }
lappend aVcFilesHxx($xlo) $aHxxFile
}
} else {
append aFilesSection "\t\t\t<Filter\n"
@@ -1789,15 +1777,9 @@ proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
}
append aFilesSection "\t\t\t</Filter>\n"
}
# macros
# append aTKDefines ";__${xlo}_DLL"
# common includes
# append anIncPaths ";..\\..\\..\\src\\${xlo}"
}
regsub -all -- {__TKINC__} $theProjTmpl $anIncPaths theProjTmpl
# regsub -all -- {__TKDEFS__} $theProjTmpl $aTKDefines theProjTmpl
regsub -all -- {__FILES__} $theProjTmpl $aFilesSection theProjTmpl
# write file
@@ -1807,12 +1789,8 @@ proc osutils:vcproj { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
close $aFile
# write filters file for vc10+
if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" || "$theVcVer" == "vc9" } {
# nothing
} elseif { "$theVcVer" == "vc10" } {
lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesX]
} else {
lappend aVcFiles [osutils:vcx1proj:filters $theOutDir $theToolKit aVcFilesX]
if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
lappend aVcFiles [osutils:vcxproj:filters $theOutDir $theToolKit aVcFilesCxx aVcFilesHxx]
}
# write resource file
@@ -1844,16 +1822,14 @@ proc osutils:tk:loadunit { loc map } {
return
}
# Returns the list of all compilable files name in a toolkit, or devunit of any type
# Tfiles lists for each unit the type of file that can be compiled.
proc osutils:tk:files { tkloc thePlatform } {
# Returns the list of all files name in a toolkit within specified list of file extensions.
proc osutils:tk:files { tkloc theExtensions } {
set Tfiles(source,nocdlpack) {source pubinclude}
set Tfiles(source,toolkit) {}
set Tfiles(source,executable) {source pubinclude}
set listloc [concat [osutils:tk:units $tkloc] $tkloc]
#puts " listloc = $listloc"
set l_comp [osutils:compilable $thePlatform]
set resultloc $listloc
set lret {}
foreach loc $resultloc {
@@ -1878,7 +1854,7 @@ proc osutils:tk:files { tkloc thePlatform } {
#puts $type
foreach f $map($type) {
#puts $f
if { [lsearch $l_comp [file extension $f]] != -1 } {
if { [lsearch $theExtensions [file extension $f]] != -1 } {
lappend lret $f
}
}
@@ -1887,10 +1863,16 @@ proc osutils:tk:files { tkloc thePlatform } {
return $lret
}
# Returns the list of all compilable files name in a toolkit.
proc osutils:tk:cxxfiles { tkloc thePlatform } { return [osutils:tk:files $tkloc [osutils:compilable $thePlatform]] }
# Returns the list of all header files name in a toolkit.
proc osutils:tk:hxxfiles { tkloc thePlatform } { return [osutils:tk:files $tkloc [osutils:fileExtensionsHeaders $thePlatform]] }
# Generate Visual Studio project file for executable
proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
set aVcFiles {}
foreach f [osutils:tk:files $theToolKit wnt] {
foreach f [osutils:tk:cxxfiles $theToolKit wnt] {
set aProjTmpl [osutils:vcproj:readtemplate $theVcVer $isUWP 1]
set aProjName [file rootname [file tail $f]]
@@ -1925,15 +1907,16 @@ proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
regsub -all -- {__TKDEP__} $aProjTmpl $aUsedLibs aProjTmpl
set aFilesSection ""
set aVcFilesX(units) ""
set aVcFilesCxx(units) ""
set aVcFilesHxx(units) ""
if { ![info exists written([file tail $f])] } {
set written([file tail $f]) 1
if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
append aFilesSection [osutils:vcxproj:file $f ""]
if { ! [info exists aVcFilesX($theToolKit)] } { lappend aVcFilesX(units) $theToolKit }
lappend aVcFilesX($theToolKit) $f
append aFilesSection [osutils:vcxproj:cxxfile $f ""]
if { ! [info exists aVcFilesCxx($theToolKit)] } { lappend aVcFilesCxx(units) $theToolKit }
lappend aVcFilesCxx($theToolKit) $f
} else {
append aFilesSection "\t\t\t<Filter\n"
append aFilesSection "\t\t\t\tName=\"$theToolKit\"\n"
@@ -1945,10 +1928,8 @@ proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
puts "Warning : in vcproj there are than one occurences for [file tail $f]"
}
#puts "$aProjTmpl $aFilesSection"
# set aTKDefines ";__${theToolKit}_DLL"
set anIncPaths "..\\..\\..\\inc"
regsub -all -- {__TKINC__} $aProjTmpl $anIncPaths aProjTmpl
# regsub -all -- {__TKDEFS__} $aProjTmpl $aTKDefines aProjTmpl
regsub -all -- {__FILES__} $aProjTmpl $aFilesSection aProjTmpl
regsub -all -- {__CONF__} $aProjTmpl Application aProjTmpl
@@ -1964,9 +1945,12 @@ proc osutils:vcprojx { theVcVer isUWP theOutDir theToolKit theGuidsMap } {
# write filters file for vc10
if { "$theVcVer" != "vc7" && "$theVcVer" != "vc8" && "$theVcVer" != "vc9" } {
lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesX]
lappend aVcFiles [osutils:vcxproj:filters $theOutDir $aProjName aVcFilesCxx aVcFilesHxx]
}
# write resource file
lappend aVcFiles [osutils:readtemplate:rc $theOutDir $aProjName]
set aCommonSettingsFileTmpl ""
if { "$theVcVer" == "vc7" || "$theVcVer" == "vc8" } {
# nothing
@@ -2149,7 +2133,7 @@ proc osutils:cbptk { theCmpl theOutDir theToolKit thePlatform} {
if [array exists written] { unset written }
foreach fxlo $resultloc {
set xlo $fxlo
set aSrcFiles [osutils:tk:files $xlo $thePlatform]
set aSrcFiles [osutils:tk:cxxfiles $xlo $thePlatform]
foreach aSrcFile [lsort $aSrcFiles] {
if { ![info exists written([file tail $aSrcFile])] } {
set written([file tail $aSrcFile]) 1
@@ -2243,7 +2227,7 @@ proc osutils:cbpx { theCmpl theOutDir theToolKit thePlatform } {
set aWokArch "$::env(ARCH)"
set aCbpFiles {}
foreach aSrcFile [osutils:tk:files $theToolKit $thePlatform] {
foreach aSrcFile [osutils:tk:cxxfiles $theToolKit $thePlatform] {
# collect list of referred libraries to link with
set aUsedLibs [list]
set aFrameworks [list]
@@ -2682,7 +2666,7 @@ proc osutils:xcdtk:deps {theToolKit theTargetType theGuidsMap theFileRefSection
set aDepToolkits [lappend [wokUtils:LIST:Purge [osutils:tk:close $theToolKit]] $theToolKit]
if { "$theTargetType" == "executable" } {
set aFile [osutils:tk:files $theToolKit mac]
set aFile [osutils:tk:cxxfiles $theToolKit mac]
set aProjName [file rootname [file tail $aFile]]
set aDepToolkits [LibToLinkX $theToolKit $aProjName]
}
@@ -2748,7 +2732,7 @@ proc osutils:xcdtk:sources {theToolKit theTargetType theSrcFileRefSection theGro
set aGuidsMap($aPackage) [OS:genGUID "xcd"]
}
set aSrcFiles [osutils:tk:files $xlo mac]
set aSrcFiles [osutils:tk:cxxfiles $xlo mac]
foreach aSrcFile [lsort $aSrcFiles] {
set aFileExt "sourcecode.cpp.cpp"

View File

@@ -0,0 +1,137 @@
#!/bin/bash
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
# ----- For compatability with external application using CASROOT -----
if [ "${CASROOT}" == "" ]; then
export CASROOT="${aScriptPath}"
fi
# ----- Define path to 3rdparty products -----
export THIRDPARTY_DIR="@3RDPARTY_DIR@"
# ----- Read script arguments -----
shopt -s nocasematch
export CASDEB="";
if [[ "$1" == "debug" ]]; then export CASDEB="d"; fi
if [[ "$1" == "d" ]]; then export CASDEB="d"; fi
if [[ "$1" == "relwithdeb" ]]; then export CASDEB="i"; fi
if [[ "$1" == "i" ]]; then export CASDEB="i"; fi
shopt -u nocasematch
# ----- Set path to 3rd party and OCCT libraries -----
anArch=`uname -m`
if [ "$anArch" != "x86_64" ] && [ "$anArch" != "ia64" ]; then
export ARCH="32";
else
export ARCH="64";
fi
aSystem=`uname -s`
if [ "$aSystem" == "Darwin" ]; then
export WOKSTATION="mac";
export ARCH="64";
else
export WOKSTATION="lin";
fi
# ----- Set local settings -----
if [ -e "${CASROOT}/custom.sh" ]; then
source "${CASROOT}/custom.sh" "${CASDEB}" "${ARCH}"
fi
THRDPARTY_PATH=""
if [ "$TCL_DIR" != "" ]; then
THRDPARTY_PATH="${TCL_DIR}:${THRDPARTY_PATH}"
fi
if [ "$TK_DIR" != "" ]; then
THRDPARTY_PATH="${TK_DIR}:${THRDPARTY_PATH}"
fi
if [ "$FREETYPE_DIR" != "" ]; then
THRDPARTY_PATH="${FREETYPE_DIR}:${THRDPARTY_PATH}"
fi
if [ "$FREEIMAGE_DIR" != "" ]; then
THRDPARTY_PATH="${FREEIMAGE_DIR}:${THRDPARTY_PATH}"
fi
if [ "$TBB_DIR" != "" ]; then
THRDPARTY_PATH="${TBB_DIR}:${THRDPARTY_PATH}"
fi
if [ "$VTK_DIR" != "" ]; then
THRDPARTY_PATH="${VTK_DIR}:${THRDPARTY_PATH}"
fi
if [ "$FFMPEG_DIR" != "" ]; then
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
fi
if [ "$QTDIR" != "" ]; then
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
fi
if [ "$TK_DIR" != "$TCL_DIR" ]; then
if [ "$TK_DIR" != "" ]; then
export TK_LIBRARY="${TK_DIR}/../lib/tk${TK_VERSION_WITH_DOT}"
fi
if [ "$TCL_DIR" != "" ]; then
export TCL_LIBRARY="${TCL_DIR}/../lib/tcl${TCL_VERSION_WITH_DOT}"
fi
fi
if [ "$LD_LIBRARY_PATH" != "" ]; then
export LD_LIBRARY_PATH="${THRDPARTY_PATH}:${LD_LIBRARY_PATH}"
else
export LD_LIBRARY_PATH="${THRDPARTY_PATH}"
fi
if [ "$CSF_OCCTBinPath" != "" ]; then
export PATH="${CSF_OCCTBinPath}:${PATH}"
fi
if [ "$CSF_OCCTLibPath" != "" ]; then
if [ "$LD_LIBRARY_PATH" != "" ]; then
export LD_LIBRARY_PATH="${CSF_OCCTLibPath}:${LD_LIBRARY_PATH}"
else
export LD_LIBRARY_PATH="${CSF_OCCTLibPath}"
fi
fi
if [ "$WOKSTATION" == "mac" ]; then
if [ "$DYLD_LIBRARY_PATH" != "" ]; then
export DYLD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${DYLD_LIBRARY_PATH}"
else
export DYLD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
fi
fi
# ----- Set envoronment variables used by OCCT -----
export CSF_LANGUAGE=us
export MMGT_CLEAR=1
export CSF_SHMessage="${CSF_OCCTResourcePath}/SHMessage"
export CSF_MDTVTexturesDirectory="${CSF_OCCTResourcePath}/Textures"
export CSF_ShadersDirectory="${CSF_OCCTResourcePath}/Shaders"
export CSF_XSMessage="${CSF_OCCTResourcePath}/XSMessage"
export CSF_TObjMessage="${CSF_OCCTResourcePath}/TObj"
export CSF_StandardDefaults="${CSF_OCCTResourcePath}/StdResource"
export CSF_PluginDefaults="${CSF_OCCTResourcePath}/StdResource"
export CSF_XCAFDefaults="${CSF_OCCTResourcePath}/StdResource"
export CSF_TObjDefaults="${CSF_OCCTResourcePath}/StdResource"
export CSF_StandardLiteDefaults="${CSF_OCCTResourcePath}/StdResource"
export CSF_IGESDefaults="${CSF_OCCTResourcePath}/XSTEPResource"
export CSF_STEPDefaults="${CSF_OCCTResourcePath}/XSTEPResource"
export CSF_XmlOcafResource="${CSF_OCCTResourcePath}/XmlOcafResource"
export CSF_MIGRATION_TYPES="${CSF_OCCTResourcePath}/StdResource/MigrationSheet.txt"
# ----- Draw Harness special stuff -----
if [ -e "${CSF_OCCTResourcePath}/DrawResources" ]; then
export DRAWHOME="${CSF_OCCTResourcePath}/DrawResources"
export CSF_DrawPluginDefaults="${CSF_OCCTResourcePath}/DrawResources"
if [ -e "${CSF_OCCTResourcePath}/DrawResources/DrawDefault" ]; then
export DRAWDEFAULT="${CSF_OCCTResourcePath}/DrawResources/DrawDefault"
fi
fi

View File

@@ -110,7 +110,7 @@
<PreprocessorDefinitions>NDEBUG;No_Exception;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<OutputFile>.\..\..\..\win32\__VCVER__\bin\__TKNAM__.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win32\__VCVER__\lib;$(CSF_OPT_LIB32);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -159,7 +159,7 @@
<PreprocessorDefinitions>_DEBUG;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<OutputFile>.\..\..\..\win32\__VCVER__\bind\__TKNAM__.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win32\__VCVER__\libd;$(CSF_OPT_LIB32D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -206,7 +206,7 @@
<PreprocessorDefinitions>NDEBUG;No_Exception;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<OutputFile>.\..\..\..\win64\__VCVER__\bin\__TKNAM__.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win64\__VCVER__\lib;$(CSF_OPT_LIB64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -255,7 +255,7 @@
<PreprocessorDefinitions>_DEBUG;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<OutputFile>.\..\..\..\win64\__VCVER__\bind\__TKNAM__.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win64\__VCVER__\libd;$(CSF_OPT_LIB64D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

View File

@@ -103,7 +103,7 @@
<PreprocessorDefinitions>NDEBUG;No_Exception;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win32\__VCVER__\lib;$(CSF_OPT_LIB32);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>__VCReleasePDB__</GenerateDebugInformation>
@@ -149,7 +149,7 @@
<PreprocessorDefinitions>_DEBUG;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win32\__VCVER__\libd;$(CSF_OPT_LIB32D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -193,7 +193,7 @@
<PreprocessorDefinitions>NDEBUG;No_Exception;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win64\__VCVER__\lib;$(CSF_OPT_LIB64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>__VCReleasePDB__</GenerateDebugInformation>
@@ -238,7 +238,7 @@
<PreprocessorDefinitions>_DEBUG;$(CSF_DEFINES);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>__TKDEP__;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>__TKDEP__</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\win64\__VCVER__\libd;$(CSF_OPT_LIB64D);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -248,7 +248,11 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
__FILES__ </ItemGroup>
__FILES__
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="__XQTNAM__.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -89,6 +89,14 @@ file (APPEND ${OCCT_CONFIG_FOR_DOXYGEN} "\nEXTERNAL_SEARCH = NO")
# Formula options
file (APPEND ${OCCT_CONFIG_FOR_DOXYGEN} "\nMATHJAX_RELPATH = ${3RDPARTY_MATHJAX_RELATIVE_PATH}")
# If MSVC is used as build system, change warning format to the one recognized by MSVC
if (MSVC)
file (APPEND ${OCCT_CONFIG_FOR_DOXYGEN} "\nWARN_FORMAT = \"$file($line): $text\"")
endif()
# Avoid Doxygen parsing messages in the build log
file (APPEND ${OCCT_CONFIG_FOR_DOXYGEN} "\nQUIET = YES")
# Copy index file to provide fast access to HTML documentation
file(COPY "${OCCT_OVERVIEW_RESOURCE_DIR}/index.html" DESTINATION "${OCCT_GENERATED_OVERVIEW_DIR}")

View File

@@ -1091,7 +1091,7 @@ The following environment variables have become redundant:
* *CSF_UnitsLexicon* and *CSF_UnitsDefinition* are no more used. Units definition (*UnitsAPI/Lexi_Expr.dat* and *UnitsAPI/Units.dat*) is now embedded into source code.
* *CSF_XSMessage* and *CSF_XHMessage* are now optional.
English messages (XSMessage/*XSTEP.us* and SHMessage/*SHAPE.us*) are now embedded into source code
English messages (XSMessage/\*XSTEP.us* and SHMessage/\*SHAPE.us*) are now embedded into source code
and automatically loaded when environment variables are not set.
* *CSF_ShadersDirectory* is not required any more, though it still can be used to load custom shaders.
Mandatory GLSL resources are now embedded into source code.
@@ -1596,6 +1596,11 @@ Since OCCT 7.4.0 exception is thrown on the attempt of taking points in case of
* The method *ImagesResult* of the class *BOPAlgo_BuilderShape* has been removed as unused. The functionality of this method can be completely replaced by the history methods *Modified* and *IsDeleted*.
* The method *TrackHistory* of the classes *BOPAlgo_RemoveFeatures* and *BRepAlgoAPI_Defeaturing* has been renamed to *SetToFillHistory*.
* The method *GetHistory* of the class *BRepAlgoAPI_Defeaturing* has been renamed to *History*.
* The classes *BRepAlgo_BooleanOperations* and *BRepAlgo_DSAccess* have been removed as obsolete. Please use the BRepAlgoAPI_* classes to perform Boolean operations.
* *BRepAlgo_DataMapOfShapeBoolean* has been removed as unused.
* *BRepAlgo_DataMapOfShapeInterference* has been removed as unused.
* *BRepAlgo_EdgeConnector* has been removed as unused.
* *BRepAlgo_SequenceOfSequenceOfInteger* has been removed as unused.
@subsection upgrade_740_localcontext Local Context removal
@@ -1614,5 +1619,69 @@ Now methods *GeomConvert::ConcatG1*, *GeomConvert::ConcatC1*, *Geom2dConvert::Co
@subsection upgrade_740_selection Changes in selection API and picked point calculation algorithm.
*SelectBasics_PickResult* structure has been extended, so that it now defines 3D point on detected entity in addition to Depth value along picking ray.
*SelectBasics_PickResult* structure has been extended, so that it now defines a 3D point on the detected entity in addition to Depth value along picking ray.
*SelectMgr_SelectingVolumeManager::Overlap()* methods have been corrected to fill in *SelectBasics_PickResult* structure (depth and 3D point) instead of only depth value, so that custom *Select3D_SensitiveEntity* implementation should be updated accordingly (including *Select3D_SensitiveSet* subclasses).
@subsection upgrade_740_ocafpersistence Document format version management improvement.
Previously Document format version restored by *DocumentRetrievalDriver* was propagated using static methods of the corresponding units (like *MDataStd* or *MNaming*) to static variables of these units and after that became accessible to Drivers of these units.
Now Document format version is available to drivers via *RelocationTable*. The Relocation table now keeps *HeaderData* of the document and a format version can be extracted in the following way: *theRelocTable.GetHeaderData()->StorageVersion()*.
Obsolete methods: *static void SetDocumentVersion (const Standard_Integer DocVersion)* and *static Standard_Integer DocumentVersion()* have been removed from *BinMDataStd*, *BinMNaming*, *XmlMDataStd* and *XmlMNaming*.
@subsection upgrade_740_changed_api_of_brepmesh BRepMesh - revision of the data model
The entire structure of *BRepMesh* component has been revised and separated into several logically connected classes.
In new version, deflection is controlled more accurately, this may be necessary to tune parameters of call of the BRepMesh algorithm on the application side to obtain the same quality of presentation and/or performance as before.
*BRepMesh_FastDiscret* and *BRepMesh_FastDiscretFace* classes have been removed.
The following changes have been introduced in the API of *BRepMesh_IncrementalMesh*, component entry point:
* Due to revised logic, *adaptiveMin* parameter of the constructor has been removed as meaningless;
* *BRepMesh_FastDiscret::Parameters* has been moved to a separate structure called *IMeshTools_Parameters*; the signatures of related methods have been changed correspondingly.
* Interface of *BRepMesh_Delaun* class has been changed.
Example of usage:
Case 1 (explicit parameters):
~~~~
#include <IMeshData_Status.hxx>
#include <IMeshTools_Parameters.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
Standard_Boolean meshing_explicit_parameters()
{
BRepMesh_IncrementalMesh aMesher (aShape, 0.1, Standard_False, 0.5, Standard_True);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
Standard_Boolean meshing_new()
{
IMeshTools_Parameters aMeshParams;
aMeshParams.Deflection = 0.1;
aMeshParams.Angle = 0.5;
aMeshParams.Relative = Standard_False;
aMeshParams.InParallel = Standard_True;
aMeshParams.MinSize = Precision::Confusion();
aMeshParams.InternalVerticesMode = Standard_True;
aMeshParams.ControlSurfaceDeflection = Standard_True;
BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
~~~~
@subsection upgrade_740_chamfer Changes in API of Chamfer algorithms
Some public methods of the class BRepFilletAPI_MakeChamfer are released from excess arguments:
- method Add for symmetric chamfer now takes only 2 arguments: distance and edge;
- method GetDistAngle now takes only 3 arguments: index of contour, distance and angle.
@subsection upgrade_740_interiorstyles Interior styles
* *Aspect_IS_HOLLOW* is now an alias to *Aspect_IS_EMPTY* and does not implicitly enables drawing mesh edges anymore.
Specify Graphic3d_AspectFillArea3d::SetDrawEdges(true) with Graphic3d_AspectFillArea3d::SetInteriorStyle(Aspect_IS_EMPTY) to get previous behavior of Aspect_IS_HOLLOW style.
* *Aspect_IS_HIDDENLINE* does not implicitly enables drawing mesh edges anymore.
Specify Graphic3d_AspectFillArea3d::SetDrawEdges(true) with Graphic3d_AspectFillArea3d::SetInteriorStyle(Aspect_IS_HIDDENLINE) to get previous behavior of Aspect_IS_HIDDENLINE style.

View File

@@ -23,7 +23,7 @@ WARNINGS = NO
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = Standard_EXPORT Standard_OVERRIDE:=override __Standard_API __Draw_API Handle(a):=Handle<a> DEFINE_STANDARD_ALLOC DEFINE_NCOLLECTION_ALLOC
PREDEFINED = Standard_EXPORT Standard_NODISCARD Standard_OVERRIDE:=override __Standard_API __Draw_API Handle(a):=Handle<a> DEFINE_STANDARD_ALLOC DEFINE_NCOLLECTION_ALLOC
GENERATE_HTML = YES
GENERATE_LATEX = NO
SEARCH_INCLUDES = YES

View File

@@ -16,7 +16,6 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = \\$file:\$line: \$text\
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.md *.dox
RECURSIVE = YES
@@ -56,6 +55,6 @@ USE_MATHJAX = YES
MATHJAX_FORMAT = HTML-CSS
# Define alias for inserting images in uniform way (both HTML and PDF)
ALIASES += figure{1}="\image html \1 \n"
ALIASES += figure{2}="\image html \1 \2 \n"
ALIASES += figure{3}="\image html \1 \2 \n"
ALIASES += figure{1}="\image html \1"
ALIASES += figure{2}="\image html \1 \2"
ALIASES += figure{3}="\image html \1 \2"

View File

@@ -16,7 +16,6 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = \\$file:\$line: \$text\
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.md *.dox
RECURSIVE = YES
@@ -49,6 +48,6 @@ LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
# Define alias for inserting images in uniform way (both HTML and PDF)
ALIASES += figure{1}="\image latex \1 \n"
ALIASES += figure{2}="\image latex \1 \2 \n"
ALIASES += figure{3}="\image latex \1 \2 width=\3 \n"
ALIASES += figure{1}="\image latex \1"
ALIASES += figure{2}="\image latex \1 \2"
ALIASES += figure{3}="\image latex \1 \2 width=\3"

View File

@@ -1891,6 +1891,21 @@ The input data for this step is as follows:
| 2.3 | Build solids <i>(SDi)</i> from *SFS*. | *BOPAlgo_BuilderSolid* |
| 2.4 | Add the solids <i>(SDi)</i> to the result | |
@subsection occt_algorithms_bop_on_opensolids Boolean operations on open solids
The Boolean operations on open solids are tricky enough that the standard approach of Boolean operations for building the result, based on the splits of solids does not work.
It happens because the algorithm for splitting solids (*BOPAlgo_BuilderSolid*) always tries to create the closed loops (shells) and make solids from them. But if the input solid is not closed, what can be expected from its splits?
For performing Boolean Operations on open solids another approach is used, which does not rely on the splits of the solids to be correct, but tries to select the splits of faces, which are necessary for the given type of operation.
The point here is that the type of Boolean operation clearly defines the states for the faces to be taken into result:
- For **COMMON** operation all the faces from the arguments located inside any solid of the opposite group must be taken;
- For **FUSE** operation all the faces from the arguments located outside of all solids of the opposite group must be taken;
- For **CUT** operation all the faces from the Objects located outside of all solids of the Tools and all faces from the Tools located inside any solid of the Objects must be taken;
- For **CUT21** operation all the faces from the Objects located inside any solid of the Tools and all faces from the Tools located outside of all solids of the Objects must be taken.
From the selected faces the result solids are built. Please note, that the result may contain as normal (closed) solids as the open ones.
Even with this approach, the correct result of Boolean operation on open solids cannot be always guaranteed.
This is explained by non-manifold nature of open solids: in some cases classification of a face depends on the point of the face chosen for classification.
@section occt_algorithms_10a Section Algorithm
@subsection occt_algorithms_10a_1 Arguments

View File

@@ -5860,6 +5860,8 @@ The following topics are covered in the eight sections of this chapter:
* Topological operations, or booleans.
* Drafting and blending.
* Defeaturing.
* Making shapes periodic in 3D space.
* Making shapes connected.
* Analysis of shapes.
@@ -7191,6 +7193,160 @@ parallel - enables the parallel processing mode.
~~~~
@subsection occt_draw_makeperiodic 3D Model Periodicity
Draw module for @ref occt_modalg_makeperiodic "making the shape periodic" includes the following commands:
* **makeperiodic** - makes the shape periodic in required directions;
* **repeatshape** - repeats the periodic shape in requested periodic direction;
* **periodictwins** - returns the periodic twins for the shape;
* **clearrepetitions** - clears all previous repetitions of the periodic shape.
@subsubsection occt_draw_makeperiodic_makeperiodic makeperiodic
The command makes the shape periodic in the required directions with the required period.
If trimming is given it trims the shape to fit the requested period.
Syntax:
~~~~
makeperiodic result shape [-x/y/z period [-trim first]]
Where:
result - resulting periodic shape;
shape - input shape to make it periodic:
-x/y/z period - option to make the shape periodic in X, Y or Z direction with the given period;
-trim first - option to trim the shape to fit the required period, starting the period in first.
~~~~
@subsubsection occt_draw_makeperiodic_repeatshape repeatshape
The command repeats the periodic shape in periodic direction requested number of time.
The result contains the all the repeated shapes glued together.
The command should be called after **makeperiodic** command.
Syntax:
~~~~
repeatshape result -x/y/z times
Where:
result - resulting shape;
-x/y/z times - direction for repetition and number of repetitions (negative number of times means the repetition in negative direction).
~~~~
@subsubsection occt_draw_makeperiodic_periodictwins periodictwins
For the given shape the command returns the identical shapes located on the opposite sides of the periodic direction.
All periodic twins should have the same geometry.
The command should be called after **makeperiodic** command.
Syntax:
~~~~
periodictwins twins shape
Where:
twins - periodic twins for the given shape
shape - shape to find the twins for
~~~~
@subsubsection occt_draw_makeperiodic_clearrepetitions clearrepetitions
The command clears all previous repetitions of the periodic shape allowing to start the repetitions over.
No arguments are needed for the command.
@subsection occt_draw_makeconnected Making the touching shapes connected
Draw module for @ref occt_modalg_makeconnected "making the touching same-dimensional shapes connected" includes the following commands:
* **makeconnected** - make the input shapes connected or glued, performs material associations;
* **cmaterialson** - returns the materials located on the requested side of a shape;
* **cmakeperiodic** - makes the connected shape periodic in requested directions;
* **crepeatshape** - repeats the periodic connected shape in requested directions requested number of times;
* **cperiodictwins** - returns all periodic twins for the shape;
* **cclearrepetitions** - clears all previous repetitions of the periodic shape, keeping the shape periodic.
@subsubsection occt_draw_makeconnected_makeconnected makeconnected
The command makes the input touching shapes connected.
Syntax:
~~~~
makeconnected result shape1 shape2 ...
Where:
result - resulting connected shape.
shape1 shape2 ... - shapes to be made connected.
~~~~
@subsubsection occt_draw_makeconnected_cmaterialson cmaterialson
The command returns the materials located on the requested side of the shape.
The command should be called after the shapes have been made connected, i.e. after the command **makeconnected**.
Syntax:
~~~~
cmaterialson result +/- shape
Where:
result - material shapes
shape - shape for which the materials are needed
+/- - side of a given shape ('+' for positive side, '-' - for negative).
~~~~
@subsubsection occt_draw_makeconnected_cmakeperiodic cmakeperiodic
The command makes the connected shape periodic in the required directions with the required period.
The command should be called after the shapes have been made connected, i.e. after the command **makeconnected**.
Syntax:
~~~~
cmakeperiodic result [-x/y/z period [-trim first]]
Where:
result - resulting periodic shape;
shape - input shape to make it periodic:
-x/y/z period - option to make the shape periodic in X, Y or Z direction with the given period;
-trim first - option to trim the shape to fit the required period, starting the period in first.
~~~~
@subsubsection occt_draw_makeconnected_crepeatshape crepeatshape
The command repeats the connected periodic shape in the required periodic directions required number of times.
The command should be called after the shapes have been made connected and periodic, i.e. after the commands **makeconnected** and **cmakeperiodic**.
Syntax:
~~~~
crepeatshape result -x/y/z times
Where:
result - resulting shape;
-x/y/z times - direction for repetition and number of repetitions (negative number of times means the repetition in negative direction).
~~~~
@subsubsection occt_draw_makeconnected_cperiodictwins cperiodictwins
The command returns all periodic twins for the shape.
The command should be called after the shapes have been made connected and periodic, i.e. after the commands **makeconnected** and **cmakeperiodic**.
Syntax:
~~~~
cperiodictwins twins shape
Where:
twins - periodic twins of a shape.
shape - input shape.
~~~~
@subsubsection occt_draw_makeconnected_cclearrepetitions cclearrepetitions
The command clears all previous repetitions of the periodic shape keeping the shape periodic.
The command should be called after the shapes have been made connected, periodic and the repetitions have been applied to the periodic shape, i.e. after the commands **makeconnected**, **cmakeperiodic** and **crepeatshape**.
Otherwise the command will have no effect.
Syntax:
~~~~
cclearrepetitions [result]
~~~~
@subsection occt_draw_7_9 Analysis of topology and geometry
Analysis of shapes includes commands to compute length, area, volumes and inertial properties, as well as to compute some aspects impacting shape validity.
@@ -8370,6 +8526,62 @@ bfillds
bsplit result
~~~~
@subsubsection occt_draw_bop_build_BOP_opensolids Alternative command for BOP
There is an alternative way to build the result of Boolean operation using the **buildbop** command, which should be run after any other building command, such as **bbuild** or **bbop** or **bsplit**.
The command has the following features:
* It is designed to work on open solids and thus uses the alternative approach for building the results (see @ref occt_algorithms_bop_on_opensolids "BOP on open solids" chapter of Boolean operations user guide).
* It allows changing the groups of Objects and Tools of the operation (even excluding some of the arguments is possible).
* History information for solids will be lost.
Syntax:
~~~~
buildbop result -o s1 [s2 ...] -t s3 [s4 ...] -op operation (common/fuse/cut/tuc)
Where:
result - result shape of the operation
s1 s2 s3 s4 - arguments (solids) of the GF operation
operation - type of boolean operation
~~~~
**Example**
~~~~
box b1 10 10 10
box b2 5 5 5 10 10 10
box b3 -5 -5 -5 10 10 10
bclearobjects
bcleartools
baddobjects b1 b2 b3
bfillds
bbuild r
# bbop command will not be available as the tools are not set
# but buildbop is available
# fuse of two
buildbop r1 -o b1 -t b2 -op fuse
buildbop r2 -o b2 -t b3 -op fuse
# fuse of all - it does not matter how the groups are formed
buildbop r3 -o b1 b2 -t b3 -op fuse
buildbop r4 -o b2 -t b1 b3 -op fuse
buildbop r5 -o b1 b2 b3 -op fuse
buildbop r6 -t b1 b2 b3 -op fuse
# common of two
buildbop r7 -o b2 -t b1 -op common
buildbop r8 -o b1 -t b3 -op common
# common
buildbop r9 -o b1 -t b2 b3 -op common
# cut
buildbop r10 -o b1 -t b2 b3 -op cut
# opposite cut
buildbop r11 -o b1 -t b2 b3 -op tuc
~~~~
@subsubsection occt_draw_bop_build_CB Cells Builder
See the @ref occt_algorithms_10c_Cells_1 "Cells Builder Usage" for the Draw usage of Cells Builder algorithm.
@@ -8495,7 +8707,7 @@ Where:
@subsubsection occt_draw_bop_options_warn Drawing warning shapes
**bdrawwarnshapes** command enables/disables drawing of waring shapes of BOP algorithms.
**bdrawwarnshapes** command enables/disables drawing of warning shapes of BOP algorithms.
Syntax:
~~~~

View File

@@ -178,10 +178,10 @@ if (!Interface_Static::SetRVal ("read.maxprecision.val",0.1))
Default value is 1.
<h4>read.stdsameparameter.mode</h4>
defines the using of *BRepLib::SameParameter*. Its possible values are:
* 0 (Off) -- *BRepLib::SameParameter* is not called,
* 1 (On) -- *BRepLib::SameParameter* is called.
*BRepLib::SameParameter* is used through *ShapeFix_Edge::SameParameter*. It ensures that the resulting edge will have the lowest tolerance taking pcurves either unmodified from the IGES file or modified by *BRepLib::SameParameter*.
defines the using of *BRepLib\::SameParameter*. Its possible values are:
* 0 (Off) -- *BRepLib\::SameParameter* is not called,
* 1 (On) -- *BRepLib\::SameParameter* is called.
*BRepLib\::SameParameter* is used through *ShapeFix_Edge\::SameParameter*. It ensures that the resulting edge will have the lowest tolerance taking pcurves either unmodified from the IGES file or modified by *BRepLib\::SameParameter*.
Read this parameter with:
~~~~~
Standard_Integer mv = Interface_Static::IVal("read.stdsameparameter.mode");
@@ -202,7 +202,7 @@ The processor also decides to re-compute either the 3D or the 2D curve even if
* the number of sub-curves in the 2D curve is different from the number of sub-curves in the 3D curve. This can be either due to different numbers of sub-curves given in the IGES file or because of splitting of curves during translation.
* 3D or 2D curve is a Circular Arc (entity type 100) starting and ending in the same point (note that this case is incorrect according to the IGES standard).
The parameter *read.surfacecurve.mode* defines which curve (3D or 2D) is used for re-computing the other one:
The parameter *read.surfacecurve.mode* defines which curve (3D or 2D) is used for re-computing the other one:
* *Default(0)* use the preference flag value in the entity's Parameter Data section. The flag values are:
* 0: no preference given,
* 1: use 2D for 142 entities and 3D for 141 entities,
@@ -400,12 +400,12 @@ reader.PrintTransferInfo (failsonly, mode);
~~~~~
displays the messages that appeared during the last invocation of *Transfer* or *TransferRoots*.
If *failsonly* is *IFSelect_FailOnly*, only fail messages will be output, if it is *IFSelect_FailAndWarn*, all messages will be output. Parameter “mode” can have *IFSelect_xxx* values where *xxx* can be:
* *GeneralCount* -- gives general statistics on the transfer (number of translated IGES entities, number of fails and warnings, etc)
* *CountByItem* -- gives the number of IGES entities with their types per message.
* *ListByItem* -- gives the number of IGES entities with their type and DE numbers per message.
* *ResultCount* -- gives the number of resulting OCCT shapes per type.
* *Mapping* -- gives mapping between roots of the IGES file and the resulting OCCT shape per IGES and OCCT type.
If *failsonly* is *IFSelect_FailOnly*, only fail messages will be output, if it is *IFSelect_FailAndWarn*, all messages will be output. Parameter “mode” can have *IFSelect_xxx* values where *xxx* can be:
* *GeneralCount* -- gives general statistics on the transfer (number of translated IGES entities, number of fails and warnings, etc)
* *CountByItem* -- gives the number of IGES entities with their types per message.
* *ListByItem* -- gives the number of IGES entities with their type and DE numbers per message.
* *ResultCount* -- gives the number of resulting OCCT shapes per type.
* *Mapping* -- gives mapping between roots of the IGES file and the resulting OCCT shape per IGES and OCCT type.
@subsection occt_iges_2_4 Mapping of IGES entities to Open CASCADE Technology shapes

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -0,0 +1,715 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-dasharray="none" shape-rendering="auto" font-family="'Dialog'" width="1032" text-rendering="auto" fill-opacity="1" contentScriptType="text/ecmascript" color-interpolation="auto" color-rendering="auto" preserveAspectRatio="xMidYMid meet" font-size="12" viewBox="0 0 1032 595" fill="black" stroke="black" image-rendering="auto" stroke-miterlimit="10" zoomAndPan="magnify" version="1.0" stroke-linecap="square" stroke-linejoin="miter" contentStyleType="text/css" font-style="normal" height="595" stroke-width="1" stroke-dashoffset="0" font-weight="normal" stroke-opacity="1">
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs"/>
<g>
<defs id="defs1">
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath1">
<path d="M131 9 L316 9 L316 206 L131 206 L131 9 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath2">
<path d="M131 9 L314 9 L314 204 L131 204 L131 9 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath3">
<path d="M146 14 L299 14 L299 32 L146 32 L146 14 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath4">
<path d="M146 14 L302 14 L302 32 L146 32 L146 14 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath5">
<path d="M136 37 L256 37 L256 55 L136 55 L136 37 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath6">
<path d="M136 37 L258 37 L258 55 L136 55 L136 37 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath7">
<path d="M136 53 L233 53 L233 71 L136 71 L136 53 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath8">
<path d="M136 53 L235 53 L235 71 L136 71 L136 53 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath9">
<path d="M136 69 L243 69 L243 87 L136 87 L136 69 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath10">
<path d="M136 69 L245 69 L245 87 L136 87 L136 69 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath11">
<path d="M136 85 L264 85 L264 103 L136 103 L136 85 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath12">
<path d="M136 85 L266 85 L266 103 L136 103 L136 85 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath13">
<path d="M136 101 L271 101 L271 119 L136 119 L136 101 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath14">
<path d="M136 101 L273 101 L273 119 L136 119 L136 101 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath15">
<path d="M136 117 L276 117 L276 145 L136 145 L136 117 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath16">
<path d="M136 117 L278 117 L278 145 L136 145 L136 117 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath17">
<path d="M136 143 L296 143 L296 171 L136 171 L136 143 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath18">
<path d="M136 143 L298 143 L298 171 L136 171 L136 143 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath19">
<path d="M136 169 L286 169 L286 187 L136 187 L136 169 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath20">
<path d="M136 169 L288 169 L288 187 L136 187 L136 169 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath21">
<path d="M132 35 L313 35 L313 203 L132 203 L132 35 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath22">
<path d="M455 44 L745 44 L745 565 L455 565 L455 44 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath23">
<path d="M455 44 L743 44 L743 563 L455 563 L455 44 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath24">
<path d="M532 49 L666 49 L666 67 L532 67 L532 49 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath25">
<path d="M532 49 L669 49 L669 67 L532 67 L532 49 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath26">
<path d="M460 72 L694 72 L694 90 L460 90 L460 72 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath27">
<path d="M460 72 L696 72 L696 90 L460 90 L460 72 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath28">
<path d="M460 88 L552 88 L552 106 L460 106 L460 88 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath29">
<path d="M460 88 L554 88 L554 106 L460 106 L460 88 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath30">
<path d="M460 104 L722 104 L722 122 L460 122 L460 104 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath31">
<path d="M460 104 L724 104 L724 122 L460 122 L460 104 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath32">
<path d="M460 120 L700 120 L700 138 L460 138 L460 120 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath33">
<path d="M460 120 L702 120 L702 138 L460 138 L460 120 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath34">
<path d="M460 136 L705 136 L705 154 L460 154 L460 136 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath35">
<path d="M460 136 L707 136 L707 154 L460 154 L460 136 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath36">
<path d="M460 152 L704 152 L704 170 L460 170 L460 152 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath37">
<path d="M460 152 L706 152 L706 170 L460 170 L460 152 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath38">
<path d="M460 168 L697 168 L697 186 L460 186 L460 168 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath39">
<path d="M460 168 L699 168 L699 186 L460 186 L460 168 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath40">
<path d="M460 184 L710 184 L710 202 L460 202 L460 184 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath41">
<path d="M460 184 L712 184 L712 202 L460 202 L460 184 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath42">
<path d="M460 200 L561 200 L561 218 L460 218 L460 200 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath43">
<path d="M460 200 L563 200 L563 218 L460 218 L460 200 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath44">
<path d="M460 216 L583 216 L583 234 L460 234 L460 216 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath45">
<path d="M460 216 L585 216 L585 234 L460 234 L460 216 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath46">
<path d="M460 232 L547 232 L547 250 L460 250 L460 232 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath47">
<path d="M460 232 L549 232 L549 250 L460 250 L460 232 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath48">
<path d="M460 248 L538 248 L538 266 L460 266 L460 248 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath49">
<path d="M460 248 L540 248 L540 266 L460 266 L460 248 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath50">
<path d="M460 264 L567 264 L567 282 L460 282 L460 264 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath51">
<path d="M460 264 L569 264 L569 282 L460 282 L460 264 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath52">
<path d="M460 280 L543 280 L543 298 L460 298 L460 280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath53">
<path d="M460 280 L545 280 L545 298 L460 298 L460 280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath54">
<path d="M460 296 L574 296 L574 314 L460 314 L460 296 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath55">
<path d="M460 296 L576 296 L576 314 L460 314 L460 296 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath56">
<path d="M460 312 L564 312 L564 330 L460 330 L460 312 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath57">
<path d="M460 312 L566 312 L566 330 L460 330 L460 312 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath58">
<path d="M460 328 L580 328 L580 346 L460 346 L460 328 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath59">
<path d="M460 328 L582 328 L582 346 L460 346 L460 328 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath60">
<path d="M460 344 L573 344 L573 362 L460 362 L460 344 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath61">
<path d="M460 344 L575 344 L575 362 L460 362 L460 344 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath62">
<path d="M460 360 L575 360 L575 378 L460 378 L460 360 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath63">
<path d="M460 360 L577 360 L577 378 L460 378 L460 360 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath64">
<path d="M460 376 L564 376 L564 394 L460 394 L460 376 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath65">
<path d="M460 376 L566 376 L566 394 L460 394 L460 376 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath66">
<path d="M460 392 L566 392 L566 410 L460 410 L460 392 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath67">
<path d="M460 392 L568 392 L568 410 L460 410 L460 392 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath68">
<path d="M460 408 L569 408 L569 426 L460 426 L460 408 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath69">
<path d="M460 408 L571 408 L571 426 L460 426 L460 408 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath70">
<path d="M460 424 L571 424 L571 442 L460 442 L460 424 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath71">
<path d="M460 424 L573 424 L573 442 L460 442 L460 424 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath72">
<path d="M460 440 L568 440 L568 458 L460 458 L460 440 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath73">
<path d="M460 440 L570 440 L570 458 L460 458 L460 440 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath74">
<path d="M460 456 L570 456 L570 474 L460 474 L460 456 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath75">
<path d="M460 456 L572 456 L572 474 L460 474 L460 456 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath76">
<path d="M460 472 L561 472 L561 490 L460 490 L460 472 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath77">
<path d="M460 472 L563 472 L563 490 L460 490 L460 472 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath78">
<path d="M460 488 L563 488 L563 506 L460 506 L460 488 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath79">
<path d="M460 488 L565 488 L565 506 L460 506 L460 488 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath80">
<path d="M460 504 L574 504 L574 522 L460 522 L460 504 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath81">
<path d="M460 504 L576 504 L576 522 L460 522 L460 504 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath82">
<path d="M460 520 L576 520 L576 538 L460 538 L460 520 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath83">
<path d="M460 520 L578 520 L578 538 L460 538 L460 520 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath84">
<path d="M460 536 L516 536 L516 554 L460 554 L460 536 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath85">
<path d="M460 536 L518 536 L518 554 L460 554 L460 536 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath86">
<path d="M456 70 L742 70 L742 562 L456 562 L456 70 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath87">
<path d="M131 225 L316 225 L316 315 L131 315 L131 225 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath88">
<path d="M131 225 L314 225 L314 313 L131 313 L131 225 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath89">
<path d="M140 230 L304 230 L304 248 L140 248 L140 230 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath90">
<path d="M140 230 L307 230 L307 248 L140 248 L140 230 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath91">
<path d="M136 253 L292 253 L292 281 L136 281 L136 253 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath92">
<path d="M136 253 L294 253 L294 281 L136 281 L136 253 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath93">
<path d="M132 251 L313 251 L313 312 L132 312 L132 251 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath94">
<path d="M131 333 L316 333 L316 423 L131 423 L131 333 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath95">
<path d="M131 333 L314 333 L314 421 L131 421 L131 333 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath96">
<path d="M148 338 L297 338 L297 356 L148 356 L148 338 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath97">
<path d="M148 338 L300 338 L300 356 L148 356 L148 338 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath98">
<path d="M136 361 L308 361 L308 389 L136 389 L136 361 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath99">
<path d="M136 361 L310 361 L310 389 L136 389 L136 361 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath100">
<path d="M132 359 L313 359 L313 420 L132 420 L132 359 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath101">
<path d="M131 441 L316 441 L316 586 L131 586 L131 441 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath102">
<path d="M131 441 L314 441 L314 584 L131 584 L131 441 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath103">
<path d="M162 446 L283 446 L283 464 L162 464 L162 446 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath104">
<path d="M162 446 L286 446 L286 464 L162 464 L162 446 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath105">
<path d="M136 469 L222 469 L222 487 L136 487 L136 469 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath106">
<path d="M136 469 L224 469 L224 487 L136 487 L136 469 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath107">
<path d="M136 485 L206 485 L206 503 L136 503 L136 485 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath108">
<path d="M136 485 L208 485 L208 503 L136 503 L136 485 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath109">
<path d="M136 501 L207 501 L207 519 L136 519 L136 501 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath110">
<path d="M136 501 L209 501 L209 519 L136 519 L136 501 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath111">
<path d="M136 517 L204 517 L204 535 L136 535 L136 517 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath112">
<path d="M136 517 L206 517 L206 535 L136 535 L136 517 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath113">
<path d="M136 533 L209 533 L209 551 L136 551 L136 533 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath114">
<path d="M136 533 L211 533 L211 551 L136 551 L136 533 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath115">
<path d="M136 549 L210 549 L210 567 L136 567 L136 549 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath116">
<path d="M136 549 L212 549 L212 567 L136 567 L136 549 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath117">
<path d="M136 565 L207 565 L207 583 L136 583 L136 565 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath118">
<path d="M136 565 L209 565 L209 583 L136 583 L136 565 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath119">
<path d="M132 467 L313 467 L313 583 L132 583 L132 467 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath120">
<path d="M851 105 L1023 105 L1023 207 L851 207 L851 105 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath121">
<path d="M851 105 L1021 105 L1021 205 L851 205 L851 105 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath122">
<path d="M856 110 L1015 110 L1015 128 L856 128 L856 110 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath123">
<path d="M856 110 L1018 110 L1018 128 L856 128 L856 110 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath124">
<path d="M856 133 L939 133 L939 151 L856 151 L856 133 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath125">
<path d="M856 133 L941 133 L941 151 L856 151 L856 133 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath126">
<path d="M856 149 L941 149 L941 167 L856 167 L856 149 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath127">
<path d="M856 149 L943 149 L943 167 L856 167 L856 149 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath128">
<path d="M856 165 L923 165 L923 183 L856 183 L856 165 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath129">
<path d="M856 165 L925 165 L925 183 L856 183 L856 165 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath130">
<path d="M852 131 L1020 131 L1020 204 L852 204 L852 131 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath131">
<path d="M-1 -1 L1033 -1 L1033 596 L-1 596 L-1 -1 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath132">
<path d="M58 177 L113 177 L113 192 L58 192 L58 177 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath133">
<path d="M124 128 L134 128 L134 137 L124 137 L124 128 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath134">
<path d="M22 211 L77 211 L77 226 L22 226 L22 211 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath135">
<path d="M124 86 L134 86 L134 95 L124 95 L124 86 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath136">
<path d="M22 436 L77 436 L77 451 L22 451 L22 436 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath137">
<path d="M124 510 L134 510 L134 519 L124 519 L124 510 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath138">
<path d="M363 129 L401 129 L401 144 L363 144 L363 129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath139">
<path d="M406 105 L460 105 L460 120 L406 120 L406 105 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath140">
<path d="M311 105 L384 105 L384 120 L311 120 L311 105 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath141">
<path d="M443 121 L458 121 L458 130 L443 130 L443 121 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath142">
<path d="M312 121 L322 121 L322 130 L312 130 L312 121 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath143">
<path d="M366 271 L404 271 L404 286 L366 286 L366 271 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath144">
<path d="M409 251 L463 251 L463 266 L409 266 L409 251 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath145">
<path d="M309 251 L362 251 L362 266 L309 266 L309 251 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath146">
<path d="M443 264 L458 264 L458 273 L443 273 L443 264 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath147">
<path d="M312 264 L322 264 L322 273 L312 273 L312 264 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath148">
<path d="M366 504 L404 504 L404 519 L366 519 L366 504 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath149">
<path d="M409 484 L463 484 L463 499 L409 499 L409 484 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath150">
<path d="M311 484 L359 484 L359 499 L311 499 L311 484 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath151">
<path d="M443 497 L458 497 L458 506 L443 506 L443 497 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath152">
<path d="M312 497 L322 497 L322 506 L312 506 L312 497 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath153">
<path d="M366 379 L404 379 L404 394 L366 394 L366 379 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath154">
<path d="M409 359 L463 359 L463 374 L409 374 L409 359 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath155">
<path d="M317 359 L356 359 L356 374 L317 374 L317 359 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath156">
<path d="M443 372 L458 372 L458 381 L443 381 L443 372 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath157">
<path d="M312 372 L322 372 L322 381 L312 381 L312 372 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath158">
<path d="M771 163 L826 163 L826 178 L771 178 L771 163 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath159">
<path d="M741 156 L751 156 L751 165 L741 165 L741 156 Z"/>
</clipPath>
</defs>
<g fill="rgb(131,122,133)" font-family="'Segoe UI'" stroke-linejoin="round" stroke="rgb(131,122,133)" font-weight="bold" stroke-width="0" stroke-miterlimit="0">
<rect x="133" y="11" clip-path="url(#clipPath1)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="193" stroke="none"/>
<rect x="134" y="12" clip-path="url(#clipPath1)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="193" stroke="none"/>
<rect x="132" y="10" clip-path="url(#clipPath2)" fill="white" width="181" rx="2.5" ry="2.5" height="193" stroke="none"/>
</g>
<g stroke-linecap="butt" fill="rgb(77,137,20)" font-family="'Segoe UI'" stroke="rgb(77,137,20)" font-weight="bold" stroke-width="1.1">
<rect x="132" y="10" clip-path="url(#clipPath2)" fill="none" width="180" rx="2.5" ry="2.5" height="192"/>
<image x="147" y="15" clip-path="url(#clipPath3)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABSUlEQVR42mNgGGjA&#13;&#10;CCIKFhz5/+DJJyj3PxAyQiQYkdggmf8IjYoyvAwTEmwYWUCc+48/MUxMswNrBhnC&#13;&#10;CNUB4QEN+c8INhtoHlSMgSF31kGwGrAB//7+Y+BgYwZrOXHjMYOFuhyDk2cB3La9&#13;&#10;O/rB9EmQnIYsxIh/EOcwwRSxMDOBNdc1r2FgYYE44dDuiWDs7FHIwAaUB8mB1IDU&#13;&#10;wgCcxcrMCFZweHUpkM0EFWOCs0GaQHJgC5gZMQ0ACTbVhjDYhnbDFbCwMCHYQBok&#13;&#10;B1LDiuQCFljwgmzwNFFhYAAqgDnR1C4bTJ8/Mg1MgzSD1ICM/AcNAxaI/n8MzExM&#13;&#10;4LDxMVMFK7h0bAYkBiAxCxbzNVODR8X//0gGgIB/w0ZopCFIWFQiJxpIygCyoXEN&#13;&#10;N2BphRdJKTCmcztqIJILwC5QURKGm0gsAOkZHAAAeQpotyJG88kAAAAASUVORK5C&#13;&#10;YII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="166" y="28" clip-path="url(#clipPath4)" fill="black" stroke="none" xml:space="preserve">IMeshTools_Parameters</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="137" y="38" clip-path="url(#clipPath5)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="51" clip-path="url(#clipPath6)" stroke="none">Deflection : Real [1]</text>
<image x="137" y="54" clip-path="url(#clipPath7)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="67" clip-path="url(#clipPath8)" stroke="none">Angle : Real [1]</text>
<image x="137" y="70" clip-path="url(#clipPath9)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="83" clip-path="url(#clipPath10)" stroke="none">MinSize : Real [1]</text>
<image x="137" y="86" clip-path="url(#clipPath11)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="99" clip-path="url(#clipPath12)" stroke="none">Relative : Boolean [1]</text>
<image x="137" y="102" clip-path="url(#clipPath13)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="115" clip-path="url(#clipPath14)" stroke="none">InParallel : Boolean [1]</text>
<image x="137" y="123" clip-path="url(#clipPath15)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="130" clip-path="url(#clipPath16)" stroke="none">InternalVerticesMode : </text>
<text xml:space="preserve" x="156" y="143" clip-path="url(#clipPath16)" stroke="none">Boolean [1]</text>
<image x="137" y="149" clip-path="url(#clipPath17)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="156" clip-path="url(#clipPath18)" stroke="none">ControlSurfaceDeflection : </text>
<text xml:space="preserve" x="156" y="169" clip-path="url(#clipPath18)" stroke="none">Boolean [1]</text>
<image x="137" y="170" clip-path="url(#clipPath19)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="183" clip-path="url(#clipPath20)" stroke="none">CleanModel : Boolean [1]</text>
</g>
<g stroke-linecap="butt" fill="rgb(77,137,20)" font-family="'Segoe UI'" stroke="rgb(77,137,20)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath21)" fill="none" x1="133" x2="312" y1="36" y2="36"/>
<rect x="457" y="46" clip-path="url(#clipPath22)" fill="rgb(131,122,133)" width="286" rx="2.5" opacity="0.2549" ry="2.5" height="517" stroke="none"/>
<rect x="458" y="47" clip-path="url(#clipPath22)" fill="rgb(131,122,133)" width="286" rx="2.5" opacity="0.2549" ry="2.5" height="517" stroke="none"/>
<rect x="456" y="45" clip-path="url(#clipPath23)" fill="white" width="286" rx="2.5" ry="2.5" height="517" stroke="none"/>
<rect x="456" y="45" clip-path="url(#clipPath23)" fill="none" width="285" rx="2.5" ry="2.5" height="516" stroke="rgb(173,127,168)"/>
<image stroke="rgb(173,127,168)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(173,127,168)" clip-path="url(#clipPath24)" preserveAspectRatio="none" height="16" x="533" y="50" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:actuate="onLoad"/>
<text x="552" y="63" clip-path="url(#clipPath25)" fill="black" stroke="none" xml:space="preserve">IMeshTools_Context</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="461" y="73" clip-path="url(#clipPath26)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="86" clip-path="url(#clipPath27)" stroke="none">myParameters : IMeshTools_Parameters [1]</text>
<image x="461" y="89" clip-path="url(#clipPath28)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="102" clip-path="url(#clipPath29)" stroke="none">myModel : [1]</text>
<image x="461" y="105" clip-path="url(#clipPath30)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="118" clip-path="url(#clipPath31)" stroke="none">myModelBuilder : IMeshTools_ModelBuilder [1]</text>
<image x="461" y="121" clip-path="url(#clipPath32)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="134" clip-path="url(#clipPath33)" stroke="none">myEdgeDiscret : IMeshTools_ModelAlgo [1]</text>
<image x="461" y="137" clip-path="url(#clipPath34)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="150" clip-path="url(#clipPath35)" stroke="none">myModelHealer : IMeshTools_ModelAlgo [1]</text>
<image x="461" y="153" clip-path="url(#clipPath36)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="166" clip-path="url(#clipPath37)" stroke="none">myPreProcessor : IMeshTools_ModelAlgo [1]</text>
<image x="461" y="169" clip-path="url(#clipPath38)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="182" clip-path="url(#clipPath39)" stroke="none">myFaceDiscret : IMeshTools_ModelAlgo [1]</text>
<image x="461" y="185" clip-path="url(#clipPath40)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVR42mNgGAWM&#13;&#10;ICJr1qH/pGqclmYH1ssCIn7/+ccwI8OeaM0ZMw/C2WADfgIN+At0Q8rUfRDR/zC3&#13;&#10;obGBYE62E8Ov339RDfjx6w/DHyjdne2G0+aSqbsZ/gAN/I5kABOI+P4TaMA/EA2R&#13;&#10;EGSBYlYELcfBwLCq2JWBk5mBYWWRK8N/IIC74BvQ5l9A7rfff8AG/P4PcTmIYIR5&#13;&#10;A6iRrckLbvOvum0IL3z/9Res6fuPPwyRTetRnH20LRCFn2OgwzDlwhVI8AABxACg&#13;&#10;zaBAXNkQyMCIFmgggGwzuhjYAFCoupWvRDgXKZVcmRAOtxnZFSAAcgnYgKsTIxhx&#13;&#10;Bv2E8P8wxSBgJ63McOjpXdRoJARgAYYtEBmJTX2gAMNmAAC8fn+eU+XlTAAAAABJRU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="198" clip-path="url(#clipPath41)" stroke="none">myPostProcessor : IMeshTools_ModelAlgo [1]</text>
<image x="461" y="201" clip-path="url(#clipPath42)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="214" clip-path="url(#clipPath43)" stroke="none">GetParameters()</text>
<image x="461" y="217" clip-path="url(#clipPath44)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="230" clip-path="url(#clipPath45)" stroke="none">ChangeParameters()</text>
<image x="461" y="233" clip-path="url(#clipPath46)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="246" clip-path="url(#clipPath47)" stroke="none">BuildModel()</text>
<image x="461" y="249" clip-path="url(#clipPath48)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="262" clip-path="url(#clipPath49)" stroke="none">GetModel()</text>
<image x="461" y="265" clip-path="url(#clipPath50)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="278" clip-path="url(#clipPath51)" stroke="none">DiscretizeEdges()</text>
<image x="461" y="281" clip-path="url(#clipPath52)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="294" clip-path="url(#clipPath53)" stroke="none">HealModel()</text>
<image x="461" y="297" clip-path="url(#clipPath54)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="310" clip-path="url(#clipPath55)" stroke="none">PreProcessModel()</text>
<image x="461" y="313" clip-path="url(#clipPath56)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="326" clip-path="url(#clipPath57)" stroke="none">DiscretizeFaces()</text>
<image x="461" y="329" clip-path="url(#clipPath58)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="342" clip-path="url(#clipPath59)" stroke="none">PostProcessModel()</text>
<image x="461" y="345" clip-path="url(#clipPath60)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="358" clip-path="url(#clipPath61)" stroke="none">SetModelBuilder()</text>
<image x="461" y="361" clip-path="url(#clipPath62)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="374" clip-path="url(#clipPath63)" stroke="none">GetModelBuilder()</text>
<image x="461" y="377" clip-path="url(#clipPath64)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="390" clip-path="url(#clipPath65)" stroke="none">SetEdgeDiscret()</text>
<image x="461" y="393" clip-path="url(#clipPath66)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="406" clip-path="url(#clipPath67)" stroke="none">GetEdgeDiscret()</text>
<image x="461" y="409" clip-path="url(#clipPath68)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="422" clip-path="url(#clipPath69)" stroke="none">SetModelHealer()</text>
<image x="461" y="425" clip-path="url(#clipPath70)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="438" clip-path="url(#clipPath71)" stroke="none">GetModelHealer()</text>
<image x="461" y="441" clip-path="url(#clipPath72)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="454" clip-path="url(#clipPath73)" stroke="none">SetPreProcessor()</text>
<image x="461" y="457" clip-path="url(#clipPath74)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="470" clip-path="url(#clipPath75)" stroke="none">GetPreProcessor()</text>
<image x="461" y="473" clip-path="url(#clipPath76)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="486" clip-path="url(#clipPath77)" stroke="none">SetFaceDiscret()</text>
<image x="461" y="489" clip-path="url(#clipPath78)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="502" clip-path="url(#clipPath79)" stroke="none">GetFaceDiscret()</text>
<image x="461" y="505" clip-path="url(#clipPath80)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="518" clip-path="url(#clipPath81)" stroke="none">SetPostProcessor()</text>
<image x="461" y="521" clip-path="url(#clipPath82)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="534" clip-path="url(#clipPath83)" stroke="none">GetPostProcessor()</text>
<image x="461" y="537" clip-path="url(#clipPath84)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="480" y="550" clip-path="url(#clipPath85)" stroke="none">Clean()</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath86)" fill="none" x1="457" x2="741" y1="71" y2="71"/>
<rect x="133" y="227" clip-path="url(#clipPath87)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="86" stroke="none"/>
<rect x="134" y="228" clip-path="url(#clipPath87)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="86" stroke="none"/>
<rect x="132" y="226" clip-path="url(#clipPath88)" fill="white" width="181" rx="2.5" ry="2.5" height="86" stroke="none"/>
<rect x="132" y="226" clip-path="url(#clipPath88)" fill="none" width="180" rx="2.5" ry="2.5" height="85"/>
<image x="141" y="231" clip-path="url(#clipPath89)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="160" y="244" clip-path="url(#clipPath90)" fill="black" stroke="none" xml:space="preserve">IMeshTools_ModelBuilder</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="137" y="259" clip-path="url(#clipPath91)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="266" clip-path="url(#clipPath92)" stroke="none">Perform(TopoDS_Shape : , </text>
<text xml:space="preserve" x="156" y="279" clip-path="url(#clipPath92)" stroke="none">IMeshTools_Parameter : )</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath93)" fill="none" x1="133" x2="312" y1="252" y2="252"/>
<rect x="133" y="335" clip-path="url(#clipPath94)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="86" stroke="none"/>
<rect x="134" y="336" clip-path="url(#clipPath94)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="86" stroke="none"/>
<rect x="132" y="334" clip-path="url(#clipPath95)" fill="white" width="181" rx="2.5" ry="2.5" height="86" stroke="none"/>
<rect x="132" y="334" clip-path="url(#clipPath95)" fill="none" width="180" rx="2.5" ry="2.5" height="85"/>
<image x="149" y="339" clip-path="url(#clipPath96)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="168" y="352" clip-path="url(#clipPath97)" fill="black" stroke="none" xml:space="preserve">IMeshTools_ModelAlgo</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="137" y="367" clip-path="url(#clipPath98)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="374" clip-path="url(#clipPath99)" stroke="none">Perform(IMeshData_Model : , </text>
<text xml:space="preserve" x="156" y="387" clip-path="url(#clipPath99)" stroke="none">IMeshTools_Parameters : )</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath100)" fill="none" x1="133" x2="312" y1="360" y2="360"/>
<rect x="133" y="443" clip-path="url(#clipPath101)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="141" stroke="none"/>
<rect x="134" y="444" clip-path="url(#clipPath101)" fill="rgb(131,122,133)" width="181" rx="2.5" opacity="0.2549" ry="2.5" height="141" stroke="none"/>
<rect x="132" y="442" clip-path="url(#clipPath102)" fill="white" width="181" rx="2.5" ry="2.5" height="141" stroke="none"/>
<rect x="132" y="442" clip-path="url(#clipPath102)" fill="none" width="180" rx="2.5" ry="2.5" height="140"/>
<image x="163" y="447" clip-path="url(#clipPath103)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="182" y="460" clip-path="url(#clipPath104)" fill="black" stroke="none" xml:space="preserve">IMeshData_Model</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="137" y="470" clip-path="url(#clipPath105)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="483" clip-path="url(#clipPath106)" stroke="none">GetMaxSize()</text>
<image x="137" y="486" clip-path="url(#clipPath107)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="499" clip-path="url(#clipPath108)" stroke="none">FacesNb()</text>
<image x="137" y="502" clip-path="url(#clipPath109)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="515" clip-path="url(#clipPath110)" stroke="none">AddFace()</text>
<image x="137" y="518" clip-path="url(#clipPath111)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="531" clip-path="url(#clipPath112)" stroke="none">GetFace()</text>
<image x="137" y="534" clip-path="url(#clipPath113)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="547" clip-path="url(#clipPath114)" stroke="none">EdgesNb()</text>
<image x="137" y="550" clip-path="url(#clipPath115)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="563" clip-path="url(#clipPath116)" stroke="none">AddEdge()</text>
<image x="137" y="566" clip-path="url(#clipPath117)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="156" y="579" clip-path="url(#clipPath118)" stroke="none">GetEdge()</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath119)" fill="none" x1="133" x2="312" y1="468" y2="468"/>
<rect x="853" y="107" clip-path="url(#clipPath120)" fill="rgb(131,122,133)" width="168" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="854" y="108" clip-path="url(#clipPath120)" fill="rgb(131,122,133)" width="168" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="852" y="106" clip-path="url(#clipPath121)" fill="white" width="168" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="852" y="106" clip-path="url(#clipPath121)" fill="none" width="167" rx="2.5" ry="2.5" height="97"/>
<image x="857" y="111" clip-path="url(#clipPath122)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="876" y="124" clip-path="url(#clipPath123)" fill="black" stroke="none" xml:space="preserve">IMeshTools_MeshBuilder</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="857" y="134" clip-path="url(#clipPath124)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="876" y="147" clip-path="url(#clipPath125)" stroke="none">SetContext()</text>
<image x="857" y="150" clip-path="url(#clipPath126)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="876" y="163" clip-path="url(#clipPath127)" stroke="none">GetContext()</text>
<image x="857" y="166" clip-path="url(#clipPath128)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="876" y="179" clip-path="url(#clipPath129)" stroke="none">Perform()</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath130)" fill="none" x1="853" x2="1019" y1="132" y2="132"/>
</g>
<g stroke-linecap="butt" font-size="11" fill="rgb(136,136,136)" font-family="'Segoe UI'" stroke-dasharray="5,5" stroke="rgb(136,136,136)" stroke-width="1.1">
<line clip-path="url(#clipPath131)" fill="none" x1="132" x2="84" y1="268" y2="268"/>
<line clip-path="url(#clipPath131)" fill="none" x1="84" x2="84" y1="268" y2="132"/>
<line clip-path="url(#clipPath131)" fill="none" x1="84" x2="132" y1="132" y2="132"/>
<text x="59" y="190" clip-path="url(#clipPath132)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath133)" fill="none" x1="125" x2="132" y1="135" y2="132" stroke-dasharray="none"/>
<line clip-path="url(#clipPath133)" fill="none" x1="132" x2="125" y1="132" y2="129" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="132" x2="48" y1="370" y2="370"/>
<line clip-path="url(#clipPath131)" fill="none" x1="48" x2="48" y1="370" y2="90"/>
<line clip-path="url(#clipPath131)" fill="none" x1="48" x2="132" y1="90" y2="90"/>
<text x="23" y="224" clip-path="url(#clipPath134)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath135)" fill="none" x1="125" x2="132" y1="93" y2="90" stroke-dasharray="none"/>
<line clip-path="url(#clipPath135)" fill="none" x1="132" x2="125" y1="90" y2="87" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="132" x2="48" y1="390" y2="390"/>
<line clip-path="url(#clipPath131)" fill="none" x1="48" x2="48" y1="390" y2="514"/>
<line clip-path="url(#clipPath131)" fill="none" x1="48" x2="132" y1="514" y2="514"/>
<text x="23" y="449" clip-path="url(#clipPath136)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath137)" fill="none" x1="125" x2="132" y1="517" y2="514" stroke-dasharray="none"/>
<line clip-path="url(#clipPath137)" fill="none" x1="132" x2="125" y1="514" y2="511" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="456" x2="313" y1="125" y2="125" stroke-dasharray="none"/>
<text x="364" y="142" clip-path="url(#clipPath138)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">caches</text>
<text x="407" y="118" clip-path="url(#clipPath139)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">context[1]</text>
<text x="312" y="118" clip-path="url(#clipPath140)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">parameters[1]</text>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath141)" points=" 456 125 450 128 444 125 450 122" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath141)" points=" 456 125 450 128 444 125 450 122"/>
<line clip-path="url(#clipPath142)" fill="none" x1="320" x2="313" y1="122" y2="125" stroke-dasharray="none"/>
<line clip-path="url(#clipPath142)" fill="none" x1="313" x2="320" y1="125" y2="128" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="456" x2="313" y1="268" y2="268" stroke-dasharray="none"/>
<text x="367" y="284" clip-path="url(#clipPath143)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">caches</text>
<text x="410" y="264" clip-path="url(#clipPath144)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">context[1]</text>
<text x="310" y="264" clip-path="url(#clipPath145)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">builder[1]</text>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath146)" points=" 456 268 450 271 444 268 450 265" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath146)" points=" 456 268 450 271 444 268 450 265"/>
<line clip-path="url(#clipPath147)" fill="none" x1="320" x2="313" y1="265" y2="268" stroke-dasharray="none"/>
<line clip-path="url(#clipPath147)" fill="none" x1="313" x2="320" y1="268" y2="271" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="456" x2="313" y1="501" y2="501" stroke-dasharray="none"/>
<text x="367" y="517" clip-path="url(#clipPath148)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">caches</text>
<text x="410" y="497" clip-path="url(#clipPath149)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">context[1]</text>
<text x="312" y="497" clip-path="url(#clipPath150)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">model[1]</text>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath151)" points=" 456 501 450 504 444 501 450 498" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath151)" points=" 456 501 450 504 444 501 450 498"/>
<line clip-path="url(#clipPath152)" fill="none" x1="320" x2="313" y1="498" y2="501" stroke-dasharray="none"/>
<line clip-path="url(#clipPath152)" fill="none" x1="313" x2="320" y1="501" y2="504" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="456" x2="313" y1="376" y2="376" stroke-dasharray="none"/>
<text x="367" y="392" clip-path="url(#clipPath153)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">caches</text>
<text x="410" y="372" clip-path="url(#clipPath154)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">context[1]</text>
<text x="318" y="372" clip-path="url(#clipPath155)" fill="black" stroke-dasharray="none" stroke="none" xml:space="preserve">algo[5]</text>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath156)" points=" 456 376 450 379 444 376 450 373" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath156)" points=" 456 376 450 379 444 376 450 373"/>
<line clip-path="url(#clipPath157)" fill="none" x1="320" x2="313" y1="373" y2="376" stroke-dasharray="none"/>
<line clip-path="url(#clipPath157)" fill="none" x1="313" x2="320" y1="376" y2="379" stroke-dasharray="none"/>
<line clip-path="url(#clipPath131)" fill="none" x1="852" x2="742" y1="160" y2="160"/>
<text x="772" y="176" clip-path="url(#clipPath158)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath159)" fill="none" x1="749" x2="742" y1="157" y2="160" stroke-dasharray="none"/>
<line clip-path="url(#clipPath159)" fill="none" x1="742" x2="749" y1="160" y2="163" stroke-dasharray="none"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 93 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 169 KiB

View File

@@ -0,0 +1,820 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-dasharray="none" shape-rendering="auto" font-family="'Dialog'" width="1514" text-rendering="auto" fill-opacity="1" contentScriptType="text/ecmascript" color-interpolation="auto" color-rendering="auto" preserveAspectRatio="xMidYMid meet" font-size="12" viewBox="0 0 1514 1571" fill="black" stroke="black" image-rendering="auto" stroke-miterlimit="10" zoomAndPan="magnify" version="1.0" stroke-linecap="square" stroke-linejoin="miter" contentStyleType="text/css" font-style="normal" height="1571" stroke-width="1" stroke-dashoffset="0" font-weight="normal" stroke-opacity="1">
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs"/>
<g>
<defs id="defs1">
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath1">
<path d="M1296 189 L1505 189 L1505 291 L1296 291 L1296 189 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath2">
<path d="M1296 189 L1503 189 L1503 289 L1296 289 L1296 189 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath3">
<path d="M1307 194 L1492 194 L1492 212 L1307 212 L1307 194 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath4">
<path d="M1307 194 L1495 194 L1495 212 L1307 212 L1307 194 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath5">
<path d="M1301 217 L1497 217 L1497 245 L1301 245 L1301 217 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath6">
<path d="M1301 217 L1499 217 L1499 245 L1301 245 L1301 217 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath7">
<path d="M1297 215 L1502 215 L1502 288 L1297 288 L1297 215 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath8">
<path d="M1296 345 L1505 345 L1505 434 L1296 434 L1296 345 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath9">
<path d="M1296 345 L1503 345 L1503 432 L1296 432 L1296 345 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath10">
<path d="M1308 350 L1490 350 L1490 368 L1308 368 L1308 350 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath11">
<path d="M1308 350 L1493 350 L1493 368 L1308 368 L1308 350 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath12">
<path d="M1297 371 L1502 371 L1502 431 L1297 431 L1297 371 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath13">
<path d="M12 165 L1168 165 L1168 1562 L12 1562 L12 165 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath14">
<path d="M12 165 L1166 165 L1166 1560 L12 1560 L12 165 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath15">
<path d="M13 170 L135 170 L135 188 L13 188 L13 170 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath16">
<path d="M13 170 L137 170 L137 188 L13 188 L13 170 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath17">
<path d="M291 189 L523 189 L523 291 L291 291 L291 189 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath18">
<path d="M291 189 L521 189 L521 289 L291 289 L291 189 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath19">
<path d="M334 194 L478 194 L478 212 L334 212 L334 194 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath20">
<path d="M334 194 L481 194 L481 212 L334 212 L334 194 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath21">
<path d="M296 217 L458 217 L458 245 L296 245 L296 217 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath22">
<path d="M296 217 L460 217 L460 245 L296 245 L296 217 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath23">
<path d="M292 215 L520 215 L520 288 L292 288 L292 215 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath24">
<path d="M446 465 L739 465 L739 567 L446 567 L446 465 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath25">
<path d="M446 465 L737 465 L737 565 L446 565 L446 465 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath26">
<path d="M482 470 L700 470 L700 488 L482 488 L482 470 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath27">
<path d="M482 470 L703 470 L703 488 L482 488 L482 470 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath28">
<path d="M447 491 L736 491 L736 564 L447 564 L447 491 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath29">
<path d="M444 777 L737 777 L737 879 L444 879 L444 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath30">
<path d="M444 777 L735 777 L735 877 L444 877 L444 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath31">
<path d="M452 782 L727 782 L727 814 L452 814 L452 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath32">
<path d="M452 782 L730 782 L730 814 L452 814 L452 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath33">
<path d="M445 817 L734 817 L734 876 L445 876 L445 817 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath34">
<path d="M792 777 L1097 777 L1097 879 L792 879 L792 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath35">
<path d="M792 777 L1095 777 L1095 877 L792 877 L792 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath36">
<path d="M796 782 L1091 782 L1091 814 L796 814 L796 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath37">
<path d="M796 782 L1094 782 L1094 814 L796 814 L796 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath38">
<path d="M793 817 L1094 817 L1094 876 L793 876 L793 817 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath39">
<path d="M74 465 L367 465 L367 567 L74 567 L74 465 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath40">
<path d="M74 465 L365 465 L365 565 L74 565 L74 465 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath41">
<path d="M118 470 L320 470 L320 488 L118 488 L118 470 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath42">
<path d="M118 470 L323 470 L323 488 L118 488 L118 470 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath43">
<path d="M75 491 L364 491 L364 564 L75 564 L75 491 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath44">
<path d="M72 777 L365 777 L365 879 L72 879 L72 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath45">
<path d="M72 777 L363 777 L363 877 L72 877 L72 777 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath46">
<path d="M75 782 L360 782 L360 814 L75 814 L75 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath47">
<path d="M75 782 L363 782 L363 814 L75 814 L75 782 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath48">
<path d="M73 817 L362 817 L362 876 L73 876 L73 817 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath49">
<path d="M36 944 L1145 944 L1145 1538 L36 1538 L36 944 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath50">
<path d="M36 944 L1143 944 L1143 1536 L36 1536 L36 944 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath51">
<path d="M37 949 L135 949 L135 967 L37 967 L37 949 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath52">
<path d="M37 949 L137 949 L137 967 L37 967 L37 949 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath53">
<path d="M492 980 L713 980 L713 1082 L492 1082 L492 980 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath54">
<path d="M492 980 L711 980 L711 1080 L492 1080 L492 980 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath55">
<path d="M499 985 L704 985 L704 1003 L499 1003 L499 985 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath56">
<path d="M499 985 L707 985 L707 1003 L499 1003 L499 985 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath57">
<path d="M493 1006 L710 1006 L710 1079 L493 1079 L493 1006 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath58">
<path d="M60 1124 L281 1124 L281 1226 L60 1226 L60 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath59">
<path d="M60 1124 L279 1124 L279 1224 L60 1224 L60 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath60">
<path d="M74 1129 L265 1129 L265 1147 L74 1147 L74 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath61">
<path d="M74 1129 L268 1129 L268 1147 L74 1147 L74 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath62">
<path d="M61 1150 L278 1150 L278 1223 L61 1223 L61 1150 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath63">
<path d="M300 1124 L521 1124 L521 1226 L300 1226 L300 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath64">
<path d="M300 1124 L519 1124 L519 1224 L300 1224 L300 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath65">
<path d="M305 1129 L513 1129 L513 1147 L305 1147 L305 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath66">
<path d="M305 1129 L516 1129 L516 1147 L305 1147 L305 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath67">
<path d="M301 1150 L518 1150 L518 1223 L301 1223 L301 1150 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath68">
<path d="M535 1124 L756 1124 L756 1226 L535 1226 L535 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath69">
<path d="M535 1124 L754 1124 L754 1224 L535 1224 L535 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath70">
<path d="M543 1129 L746 1129 L746 1147 L543 1147 L543 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath71">
<path d="M543 1129 L749 1129 L749 1147 L543 1147 L543 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath72">
<path d="M536 1150 L753 1150 L753 1223 L536 1223 L536 1150 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath73">
<path d="M775 1124 L995 1124 L995 1226 L775 1226 L775 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath74">
<path d="M775 1124 L993 1124 L993 1224 L775 1224 L775 1124 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath75">
<path d="M776 1129 L991 1129 L991 1147 L776 1147 L776 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath76">
<path d="M776 1129 L994 1129 L994 1147 L776 1147 L776 1129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath77">
<path d="M776 1150 L992 1150 L992 1223 L776 1223 L776 1150 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath78">
<path d="M649 1280 L869 1280 L869 1382 L649 1382 L649 1280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath79">
<path d="M649 1280 L867 1280 L867 1380 L649 1380 L649 1280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath80">
<path d="M661 1285 L855 1285 L855 1303 L661 1303 L661 1285 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath81">
<path d="M661 1285 L858 1285 L858 1303 L661 1303 L661 1285 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath82">
<path d="M650 1306 L866 1306 L866 1379 L650 1379 L650 1306 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath83">
<path d="M900 1280 L1119 1280 L1119 1382 L900 1382 L900 1280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath84">
<path d="M900 1280 L1117 1280 L1117 1380 L900 1380 L900 1280 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath85">
<path d="M906 1285 L1110 1285 L1110 1303 L906 1303 L906 1285 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath86">
<path d="M906 1285 L1113 1285 L1113 1303 L906 1303 L906 1285 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath87">
<path d="M901 1306 L1116 1306 L1116 1379 L901 1379 L901 1306 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath88">
<path d="M852 1413 L1119 1413 L1119 1515 L852 1515 L852 1413 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath89">
<path d="M852 1413 L1117 1413 L1117 1513 L852 1513 L852 1413 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath90">
<path d="M856 1418 L1112 1418 L1112 1436 L856 1436 L856 1418 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath91">
<path d="M856 1418 L1115 1418 L1115 1436 L856 1436 L856 1418 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath92">
<path d="M853 1439 L1116 1439 L1116 1512 L853 1512 L853 1439 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath93">
<path d="M290 321 L523 321 L523 423 L290 423 L290 321 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath94">
<path d="M290 321 L521 321 L521 421 L290 421 L290 321 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath95">
<path d="M322 326 L489 326 L489 344 L322 344 L322 326 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath96">
<path d="M322 326 L492 326 L492 344 L322 344 L322 326 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath97">
<path d="M291 347 L520 347 L520 420 L291 420 L291 347 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath98">
<path d="M822 321 L1067 321 L1067 423 L822 423 L822 321 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath99">
<path d="M822 321 L1065 321 L1065 421 L822 421 L822 321 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath100">
<path d="M834 326 L1053 326 L1053 344 L834 344 L834 326 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath101">
<path d="M834 326 L1056 326 L1056 344 L834 344 L834 326 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath102">
<path d="M823 347 L1064 347 L1064 420 L823 420 L823 347 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath103">
<path d="M276 621 L538 621 L538 723 L276 723 L276 621 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath104">
<path d="M276 621 L536 621 L536 721 L276 721 L276 621 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath105">
<path d="M294 626 L518 626 L518 658 L294 658 L294 626 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath106">
<path d="M294 626 L521 626 L521 658 L294 658 L294 626 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath107">
<path d="M294 626 L520 626 L520 658 L294 658 L294 626 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath108">
<path d="M277 661 L535 661 L535 720 L277 720 L277 661 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath109">
<path d="M792 9 L986 9 L986 111 L792 111 L792 9 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath110">
<path d="M792 9 L984 9 L984 109 L792 109 L792 9 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath111">
<path d="M812 14 L963 14 L963 32 L812 32 L812 14 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath112">
<path d="M812 14 L966 14 L966 32 L812 32 L812 14 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath113">
<path d="M793 35 L983 35 L983 108 L793 108 L793 35 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath114">
<path d="M-1 -1 L1515 -1 L1515 1572 L-1 1572 L-1 -1 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath115">
<path d="M22 597 L365 597 L365 615 L22 615 L22 597 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath116">
<path d="M22 597 L367 597 L367 615 L22 615 L22 597 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath117">
<path d="M366 616 L377 616 L377 624 L366 624 L366 616 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath118">
<path d="M828 908 L1001 908 L1001 926 L828 926 L828 908 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath119">
<path d="M828 908 L1003 908 L1003 926 L828 926 L828 908 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath120">
<path d="M904 875 L915 875 L915 883 L904 883 L904 875 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath121">
<path d="M597 1078 L608 1078 L608 1089 L597 1089 L597 1078 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath122">
<path d="M400 419 L411 419 L411 430 L400 430 L400 419 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath123">
<path d="M880 1222 L891 1222 L891 1233 L880 1233 L880 1222 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath124">
<path d="M127 902 L300 902 L300 920 L127 920 L127 902 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath125">
<path d="M127 902 L302 902 L302 920 L127 920 L127 902 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath126">
<path d="M252 875 L263 875 L263 883 L252 883 L252 875 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath127">
<path d="M434 597 L794 597 L794 615 L434 615 L434 597 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath128">
<path d="M434 597 L796 597 L796 615 L434 615 L434 597 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath129">
<path d="M446 616 L457 616 L457 624 L446 624 L446 616 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath130">
<path d="M1004 1378 L1015 1378 L1015 1389 L1004 1389 L1004 1378 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath131">
<path d="M733 823 L743 823 L743 832 L733 832 L733 823 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath132">
<path d="M402 719 L413 719 L413 730 L402 730 L402 719 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath133">
<path d="M408 896 L581 896 L581 914 L408 914 L408 896 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath134">
<path d="M408 896 L583 896 L583 914 L408 914 L408 896 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath135">
<path d="M586 875 L595 875 L595 885 L586 885 L586 875 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath136">
<path d="M666 359 L721 359 L721 374 L666 374 L666 359 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath137">
<path d="M815 372 L825 372 L825 381 L815 381 L815 372 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath138">
<path d="M401 287 L412 287 L412 298 L401 298 L401 287 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath139">
<path d="M1394 287 L1405 287 L1405 298 L1394 298 L1394 287 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath140">
<path d="M1164 394 L1174 394 L1174 403 L1164 403 L1164 394 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath141">
<path d="M579 123 L634 123 L634 138 L579 138 L579 123 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath142">
<path d="M408 185 L418 185 L418 194 L408 194 L408 185 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath143">
<path d="M1140 129 L1195 129 L1195 144 L1140 144 L1140 129 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath144">
<path d="M1385 185 L1395 185 L1395 194 L1385 194 L1385 185 Z"/>
</clipPath>
</defs>
<g fill="rgb(131,122,133)" font-family="'Segoe UI'" stroke-linejoin="round" stroke="rgb(131,122,133)" font-weight="bold" stroke-width="0" stroke-miterlimit="0">
<rect x="1298" y="191" clip-path="url(#clipPath1)" width="205" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="1299" y="192" clip-path="url(#clipPath1)" width="205" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="1297" y="190" clip-path="url(#clipPath2)" fill="white" width="205" rx="2.5" ry="2.5" height="98" stroke="none"/>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<rect x="1297" y="190" clip-path="url(#clipPath2)" fill="none" width="204" rx="2.5" ry="2.5" height="97"/>
<image x="1308" y="195" clip-path="url(#clipPath3)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="1327" y="208" clip-path="url(#clipPath4)" fill="black" stroke="none" xml:space="preserve">IMeshTools_MeshAlgoFactory</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="1302" y="223" clip-path="url(#clipPath5)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="1321" y="230" clip-path="url(#clipPath6)" stroke="none">GetAlgo(GeomAbs_SurfaceType : , </text>
<text xml:space="preserve" x="1321" y="243" clip-path="url(#clipPath6)" stroke="none">IMeshTools_Parameters : )</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath7)" fill="none" x1="1298" x2="1501" y1="216" y2="216"/>
<rect x="1298" y="347" clip-path="url(#clipPath8)" fill="rgb(131,122,133)" width="205" rx="2.5" opacity="0.2549" ry="2.5" height="85" stroke="none"/>
<rect x="1299" y="348" clip-path="url(#clipPath8)" fill="rgb(131,122,133)" width="205" rx="2.5" opacity="0.2549" ry="2.5" height="85" stroke="none"/>
<rect x="1297" y="346" clip-path="url(#clipPath9)" fill="white" width="205" rx="2.5" ry="2.5" height="85" stroke="none"/>
<rect x="1297" y="346" clip-path="url(#clipPath9)" fill="none" width="204" rx="2.5" ry="2.5" height="84" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath10)" preserveAspectRatio="none" height="16" x="1309" y="351" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="1328" y="364" clip-path="url(#clipPath11)" fill="black" stroke="none" xml:space="preserve">BRepMesh_MeshAlgoFactory</text>
<line clip-path="url(#clipPath12)" fill="none" x1="1298" x2="1501" y1="372" y2="372" stroke="rgb(39,76,114)"/>
<rect x="14" y="167" clip-path="url(#clipPath13)" fill="rgb(131,122,133)" width="1152" rx="2.5" opacity="0.2549" ry="2.5" height="1393" stroke="none"/>
<rect x="15" y="168" clip-path="url(#clipPath13)" fill="rgb(131,122,133)" width="1152" rx="2.5" opacity="0.2549" ry="2.5" height="1393" stroke="none"/>
<rect x="13" y="166" clip-path="url(#clipPath14)" fill="white" width="1152" rx="2.5" ry="2.5" height="1393" stroke="none"/>
<rect x="13" y="166" clip-path="url(#clipPath14)" fill="none" width="1151" rx="2.5" ry="2.5" height="1392" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath15)" preserveAspectRatio="none" height="16" x="14" y="171" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAWUlEQVR42mNgGPKA&#13;&#10;EUQoZCz4j0vBgxkJjPgMYIEx7k+Px5BUzFxIuQvwAZDr4C7YUBdAkuaApg2oXgAB&#13;&#10;MV5+kl3BRGksoLiAnZlCA5gZKTWAiQIDYKE6AgEAAu0P6M4KKrgAAAAASUVORK5C&#13;&#10;YII=" xlink:actuate="onLoad"/>
<text x="33" y="184" clip-path="url(#clipPath16)" fill="black" stroke="none" xml:space="preserve">Triangulation Algo</text>
<rect x="293" y="191" clip-path="url(#clipPath17)" fill="rgb(131,122,133)" width="228" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="294" y="192" clip-path="url(#clipPath17)" fill="rgb(131,122,133)" width="228" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="292" y="190" clip-path="url(#clipPath18)" fill="white" width="228" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="292" y="190" clip-path="url(#clipPath18)" fill="none" width="227" rx="2.5" ry="2.5" height="97"/>
<image x="335" y="195" clip-path="url(#clipPath19)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmMHsEzceMVhoyDFYVK6EazjRHg4Xh2iAOIcJ2VQWZiawooKF&#13;&#10;x8HsM12RYHEQDeKDxEHyIDYMoBnACFZ0oTcKzAZhmDgIg8QhhjNiN4AVaPKEeEsG&#13;&#10;g+JlYDYr1CYYGyQOkmfF6gJgELMCTfYyUYEqYmTQLlgClgLRID5IHCQPYv+DhgEL&#13;&#10;Qv8/BmYmiNN8zVTB9N2pcSghDxOHqEczAAT8GjaB08F/NBIGECkEyGZkxDRgaYUX&#13;&#10;0ekgpnM7ZiCSA1iwmUq2AUvKPQfQCypKwiR5AaSeKgAABcZdRqE6GaQAAAAASUVO&#13;&#10;RK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="354" y="208" clip-path="url(#clipPath20)" fill="black" stroke="none" xml:space="preserve">IMeshTools_MeshAlgo</text>
</g>
<g stroke-width="1.1" font-size="11" font-family="'Segoe UI'" stroke-linecap="butt">
<image x="297" y="223" clip-path="url(#clipPath21)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACM0lEQVR42sVTX0hT&#13;&#10;URz+7p3OCIqkaMLq0R6CCIRMaCMyr9ushkT17Fq9RNk/iJBk5z5s+BAhBQYh6Hyp&#13;&#10;B5W0NufcbCuNFcToIQrxz5g0IsVE5u52d+89HScMYw56CPo9nHN+/L7z8fGd7wD/&#13;&#10;u3TlBgIJ0nmlmljb3GQ2OiCWw/FbmyYxQGG+SzfOE+HXePfkNgLhwc3hiZvUSsK0&#13;&#10;rAKLK0gnwq8w+fA6vF950v/gCnZWVaGxoQ4jC3oy+agdnU/7IVzuIvNRb1ERV5Ri&#13;&#10;aqejXTcASsFxKjRaCbaggtfYtAIKVIbWcO5+DzD1mCtRQJMfxBczHGk1NSCfB3yx&#13;&#10;OGYWF/ElkcLBmhrICnCxswd0y+UigcUVonPqHuK+5kClTofI5zhjVNDr/4RjtUbM&#13;&#10;/kjhQLUBx48cRWhpB2l2uslcZNPYgonjzDDP1TZsqFxeyUHTFPSNxRH1nMez8Rh4&#13;&#10;lcP31RwUlcLjdCAYfPnnK9iEs+joHUBiOYOVjASOee04U4dTHUNw2uqh8TqsrctI&#13;&#10;/FpnuD4IFjtKTCwUM9JxoRW8wnjlFGOn0BiE0xug6vTwDg5Bm+7mtg+S+Ra1t7RA&#13;&#10;zgGSKiNHdyPNVbJ9FyRNRUZWcfhQLb7l9xEkY2JJkMwnGzHq92E1l8XImA8/M2ms&#13;&#10;ScCSlMWwP4h0VsJwwI/TTbbtg5R8+1ysv3SPTE9FCk+VpPvJXqMRHyOsf9/NLagG&#13;&#10;Igh2hFwC91efxOp6Q2G6Q5vF0vj+0/oNRdDxkTDUjqQAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text xml:space="preserve" x="316" y="230" clip-path="url(#clipPath22)" stroke="none">Perform(IMeshData_Face : , </text>
<text xml:space="preserve" x="316" y="243" clip-path="url(#clipPath22)" stroke="none">IMeshTools_Parameters : )</text>
</g>
<g stroke-linecap="butt" fill="rgb(173,127,168)" font-family="'Segoe UI'" stroke="rgb(173,127,168)" font-weight="bold" stroke-width="1.1">
<line clip-path="url(#clipPath23)" fill="none" x1="293" x2="519" y1="216" y2="216"/>
<rect x="448" y="467" clip-path="url(#clipPath24)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="449" y="468" clip-path="url(#clipPath24)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="447" y="466" clip-path="url(#clipPath25)" fill="white" width="289" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="447" y="466" clip-path="url(#clipPath25)" fill="none" width="288" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath26)" preserveAspectRatio="none" height="16" x="483" y="471" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="502" y="484" clip-path="url(#clipPath27)" fill="black" stroke="none" xml:space="preserve">BRepMesh_DelaunayBaseMeshAlgo</text>
<line clip-path="url(#clipPath28)" fill="none" x1="448" x2="735" y1="492" y2="492" stroke="rgb(39,76,114)"/>
<rect x="446" y="779" clip-path="url(#clipPath29)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="447" y="780" clip-path="url(#clipPath29)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="445" y="778" clip-path="url(#clipPath30)" fill="white" width="289" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="445" y="778" clip-path="url(#clipPath30)" fill="none" width="288" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath31)" preserveAspectRatio="none" height="16" x="453" y="790" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="472" y="796" clip-path="url(#clipPath32)" fill="black" stroke="none" xml:space="preserve">BRepMesh_DelaunayNodeInsertionMeshAlgo </text>
<text x="472" y="811" clip-path="url(#clipPath32)" fill="black" stroke="none" xml:space="preserve">&lt;RangeSplitter&gt;</text>
<line clip-path="url(#clipPath33)" fill="none" x1="446" x2="733" y1="818" y2="818" stroke="rgb(39,76,114)"/>
<rect x="794" y="779" clip-path="url(#clipPath34)" fill="rgb(131,122,133)" width="301" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="795" y="780" clip-path="url(#clipPath34)" fill="rgb(131,122,133)" width="301" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="793" y="778" clip-path="url(#clipPath35)" fill="white" width="301" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="793" y="778" clip-path="url(#clipPath35)" fill="none" width="300" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath36)" preserveAspectRatio="none" height="16" x="797" y="790" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="816" y="796" clip-path="url(#clipPath37)" fill="black" stroke="none" xml:space="preserve">BRepMesh_DelaunayDeflectionControlMeshAlgo </text>
<text x="816" y="811" clip-path="url(#clipPath37)" fill="black" stroke="none" xml:space="preserve">&lt;RangeSplitter&gt;</text>
<line clip-path="url(#clipPath38)" fill="none" x1="794" x2="1093" y1="818" y2="818" stroke="rgb(39,76,114)"/>
<rect x="76" y="467" clip-path="url(#clipPath39)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="77" y="468" clip-path="url(#clipPath39)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="75" y="466" clip-path="url(#clipPath40)" fill="white" width="289" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="75" y="466" clip-path="url(#clipPath40)" fill="none" width="288" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath41)" preserveAspectRatio="none" height="16" x="119" y="471" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="138" y="484" clip-path="url(#clipPath42)" fill="black" stroke="none" xml:space="preserve">BRepMesh_SweepLineMeshAlgo</text>
<line clip-path="url(#clipPath43)" fill="none" x1="76" x2="363" y1="492" y2="492" stroke="rgb(39,76,114)"/>
<rect x="74" y="779" clip-path="url(#clipPath44)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="75" y="780" clip-path="url(#clipPath44)" fill="rgb(131,122,133)" width="289" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="73" y="778" clip-path="url(#clipPath45)" fill="white" width="289" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="73" y="778" clip-path="url(#clipPath45)" fill="none" width="288" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath46)" preserveAspectRatio="none" height="16" x="76" y="790" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="95" y="796" clip-path="url(#clipPath47)" fill="black" stroke="none" xml:space="preserve">BRepMesh_SweepLineNodeInsertionMeshAlgo </text>
<text x="95" y="811" clip-path="url(#clipPath47)" fill="black" stroke="none" xml:space="preserve">&lt;RangeSplitter&gt;</text>
<line clip-path="url(#clipPath48)" fill="none" x1="74" x2="361" y1="818" y2="818" stroke="rgb(39,76,114)"/>
<rect x="38" y="946" clip-path="url(#clipPath49)" fill="rgb(131,122,133)" width="1105" rx="2.5" opacity="0.2549" ry="2.5" height="590" stroke="none"/>
<rect x="39" y="947" clip-path="url(#clipPath49)" fill="rgb(131,122,133)" width="1105" rx="2.5" opacity="0.2549" ry="2.5" height="590" stroke="none"/>
<rect x="37" y="945" clip-path="url(#clipPath50)" fill="white" width="1105" rx="2.5" ry="2.5" height="590" stroke="none"/>
<rect x="37" y="945" clip-path="url(#clipPath50)" fill="none" width="1104" rx="2.5" ry="2.5" height="589" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath51)" preserveAspectRatio="none" height="16" x="38" y="950" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAWUlEQVR42mNgGPKA&#13;&#10;EUQoZCz4j0vBgxkJjPgMYIEx7k+Px5BUzFxIuQvwAZDr4C7YUBdAkuaApg2oXgAB&#13;&#10;MV5+kl3BRGksoLiAnZlCA5gZKTWAiQIDYKE6AgEAAu0P6M4KKrgAAAAASUVORK5C&#13;&#10;YII=" xlink:actuate="onLoad"/>
<text x="57" y="963" clip-path="url(#clipPath52)" fill="black" stroke="none" xml:space="preserve">RangeSplitter</text>
<rect x="494" y="982" clip-path="url(#clipPath53)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="495" y="983" clip-path="url(#clipPath53)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="493" y="981" clip-path="url(#clipPath54)" fill="white" width="217" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="493" y="981" clip-path="url(#clipPath54)" fill="none" width="216" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath55)" preserveAspectRatio="none" height="16" x="500" y="986" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="519" y="999" clip-path="url(#clipPath56)" fill="black" stroke="none" xml:space="preserve">BRepMesh_DefaultRangeSplitter</text>
<line clip-path="url(#clipPath57)" fill="none" x1="494" x2="709" y1="1007" y2="1007" stroke="rgb(39,76,114)"/>
<rect x="62" y="1126" clip-path="url(#clipPath58)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="63" y="1127" clip-path="url(#clipPath58)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="61" y="1125" clip-path="url(#clipPath59)" fill="white" width="217" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="61" y="1125" clip-path="url(#clipPath59)" fill="none" width="216" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath60)" preserveAspectRatio="none" height="16" x="75" y="1130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="94" y="1143" clip-path="url(#clipPath61)" fill="black" stroke="none" xml:space="preserve">BRepMesh_ConeRangeSplitter</text>
<line clip-path="url(#clipPath62)" fill="none" x1="62" x2="277" y1="1151" y2="1151" stroke="rgb(39,76,114)"/>
<rect x="302" y="1126" clip-path="url(#clipPath63)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="303" y="1127" clip-path="url(#clipPath63)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="301" y="1125" clip-path="url(#clipPath64)" fill="white" width="217" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="301" y="1125" clip-path="url(#clipPath64)" fill="none" width="216" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath65)" preserveAspectRatio="none" height="16" x="306" y="1130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="325" y="1143" clip-path="url(#clipPath66)" fill="black" stroke="none" xml:space="preserve">BRepMesh_CylinderRangeSplitter</text>
<line clip-path="url(#clipPath67)" fill="none" x1="302" x2="517" y1="1151" y2="1151" stroke="rgb(39,76,114)"/>
<rect x="537" y="1126" clip-path="url(#clipPath68)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="538" y="1127" clip-path="url(#clipPath68)" fill="rgb(131,122,133)" width="217" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="536" y="1125" clip-path="url(#clipPath69)" fill="white" width="217" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="536" y="1125" clip-path="url(#clipPath69)" fill="none" width="216" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath70)" preserveAspectRatio="none" height="16" x="544" y="1130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="563" y="1143" clip-path="url(#clipPath71)" fill="black" stroke="none" xml:space="preserve">BRepMesh_SphereRangeSplitter</text>
<line clip-path="url(#clipPath72)" fill="none" x1="537" x2="752" y1="1151" y2="1151" stroke="rgb(39,76,114)"/>
<rect x="777" y="1126" clip-path="url(#clipPath73)" fill="rgb(131,122,133)" width="216" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="778" y="1127" clip-path="url(#clipPath73)" fill="rgb(131,122,133)" width="216" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="776" y="1125" clip-path="url(#clipPath74)" fill="white" width="216" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="776" y="1125" clip-path="url(#clipPath74)" fill="none" width="215" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath75)" preserveAspectRatio="none" height="16" x="777" y="1130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="796" y="1143" clip-path="url(#clipPath76)" fill="black" stroke="none" xml:space="preserve">BRepMesh_UVParamRangeSplitter</text>
<line clip-path="url(#clipPath77)" fill="none" x1="777" x2="991" y1="1151" y2="1151" stroke="rgb(39,76,114)"/>
<rect x="651" y="1282" clip-path="url(#clipPath78)" fill="rgb(131,122,133)" width="216" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="652" y="1283" clip-path="url(#clipPath78)" fill="rgb(131,122,133)" width="216" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="650" y="1281" clip-path="url(#clipPath79)" fill="white" width="216" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="650" y="1281" clip-path="url(#clipPath79)" fill="none" width="215" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath80)" preserveAspectRatio="none" height="16" x="662" y="1286" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="681" y="1299" clip-path="url(#clipPath81)" fill="black" stroke="none" xml:space="preserve">BRepMesh_TorusRangeSplitter</text>
<line clip-path="url(#clipPath82)" fill="none" x1="651" x2="865" y1="1307" y2="1307" stroke="rgb(39,76,114)"/>
<rect x="902" y="1282" clip-path="url(#clipPath83)" fill="rgb(131,122,133)" width="215" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="903" y="1283" clip-path="url(#clipPath83)" fill="rgb(131,122,133)" width="215" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="901" y="1281" clip-path="url(#clipPath84)" fill="white" width="215" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="901" y="1281" clip-path="url(#clipPath84)" fill="none" width="214" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath85)" preserveAspectRatio="none" height="16" x="907" y="1286" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="926" y="1299" clip-path="url(#clipPath86)" fill="black" stroke="none" xml:space="preserve">BRepMesh_NURBSRangeSplitter</text>
<line clip-path="url(#clipPath87)" fill="none" x1="902" x2="1115" y1="1307" y2="1307" stroke="rgb(39,76,114)"/>
<rect x="854" y="1415" clip-path="url(#clipPath88)" fill="rgb(131,122,133)" width="263" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="855" y="1416" clip-path="url(#clipPath88)" fill="rgb(131,122,133)" width="263" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="853" y="1414" clip-path="url(#clipPath89)" fill="white" width="263" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="853" y="1414" clip-path="url(#clipPath89)" fill="none" width="262" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath90)" preserveAspectRatio="none" height="16" x="857" y="1419" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="876" y="1432" clip-path="url(#clipPath91)" fill="black" stroke="none" xml:space="preserve">BRepMesh_BoundaryParamsRangeSplitter</text>
<line clip-path="url(#clipPath92)" fill="none" x1="854" x2="1115" y1="1440" y2="1440" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath49)" fill="none" x1="38" x2="134" y1="971" y2="971" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath49)" fill="none" x1="134" x2="134" y1="971" y2="971" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath49)" fill="none" x1="134" x2="139" y1="971" y2="966" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath49)" fill="none" x1="139" x2="139" y1="966" y2="966" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath49)" fill="none" x1="139" x2="139" y1="966" y2="945" stroke="rgb(39,76,114)"/>
<rect x="292" y="323" clip-path="url(#clipPath93)" fill="rgb(131,122,133)" width="229" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="293" y="324" clip-path="url(#clipPath93)" fill="rgb(131,122,133)" width="229" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="291" y="322" clip-path="url(#clipPath94)" fill="white" width="229" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="291" y="322" clip-path="url(#clipPath94)" fill="none" width="228" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath95)" preserveAspectRatio="none" height="16" x="323" y="327" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="342" y="340" clip-path="url(#clipPath96)" fill="black" stroke="none" xml:space="preserve">BRepMesh_BaseMeshAlgo</text>
<line clip-path="url(#clipPath97)" fill="none" x1="292" x2="519" y1="348" y2="348" stroke="rgb(39,76,114)"/>
<rect x="824" y="323" clip-path="url(#clipPath98)" fill="rgb(131,122,133)" width="241" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="825" y="324" clip-path="url(#clipPath98)" fill="rgb(131,122,133)" width="241" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="823" y="322" clip-path="url(#clipPath99)" fill="white" width="241" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="823" y="322" clip-path="url(#clipPath99)" fill="none" width="240" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath100)" preserveAspectRatio="none" height="16" x="835" y="327" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="854" y="340" clip-path="url(#clipPath101)" fill="black" stroke="none" xml:space="preserve">BRepMesh_DataStructureOfDelaun</text>
<line clip-path="url(#clipPath102)" fill="none" x1="824" x2="1063" y1="348" y2="348" stroke="rgb(39,76,114)"/>
<rect x="278" y="623" clip-path="url(#clipPath103)" fill="rgb(131,122,133)" width="258" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="279" y="624" clip-path="url(#clipPath103)" fill="rgb(131,122,133)" width="258" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="277" y="622" clip-path="url(#clipPath104)" fill="white" width="258" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="277" y="622" clip-path="url(#clipPath104)" fill="none" width="257" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath105)" preserveAspectRatio="none" height="16" x="295" y="634" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="314" y="640" clip-path="url(#clipPath106)" fill="black" stroke="none" xml:space="preserve">BRepMesh_NodeInsertionMeshAlgo </text>
<text x="314" y="655" clip-path="url(#clipPath107)" fill="black" stroke="none" xml:space="preserve">&lt;RangeSplitter, BaseClass&gt;</text>
<line clip-path="url(#clipPath108)" fill="none" x1="278" x2="534" y1="662" y2="662" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath13)" fill="none" x1="14" x2="134" y1="192" y2="192" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath13)" fill="none" x1="134" x2="134" y1="192" y2="192" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath13)" fill="none" x1="134" x2="139" y1="192" y2="187" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath13)" fill="none" x1="139" x2="139" y1="187" y2="187" stroke="rgb(39,76,114)"/>
<line clip-path="url(#clipPath13)" fill="none" x1="139" x2="139" y1="187" y2="166" stroke="rgb(39,76,114)"/>
<rect x="794" y="11" clip-path="url(#clipPath109)" fill="rgb(131,122,133)" width="190" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="795" y="12" clip-path="url(#clipPath109)" fill="rgb(131,122,133)" width="190" rx="2.5" opacity="0.2549" ry="2.5" height="98" stroke="none"/>
<rect x="793" y="10" clip-path="url(#clipPath110)" fill="white" width="190" rx="2.5" ry="2.5" height="98" stroke="none"/>
<rect x="793" y="10" clip-path="url(#clipPath110)" fill="none" width="189" rx="2.5" ry="2.5" height="97" stroke="rgb(39,76,114)"/>
<image stroke="rgb(39,76,114)" width="16" xlink:show="embed" xlink:type="simple" fill="rgb(39,76,114)" clip-path="url(#clipPath111)" preserveAspectRatio="none" height="16" x="813" y="15" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAr0lEQVR42mNkgIKC&#13;&#10;BUf+P3jyCchiBOL/QMgIYTFCREDg/38GOFCU4WWYkGDDyAITuP/4E8OkNDsGYkHu&#13;&#10;rINgGm7Av7//GNjZmIk2gOHff1QDwBxmJgZSAZoBjJQZwEqRC4BBzEqCC/6hh8H/&#13;&#10;//8YmJmIN+D/fyyB6NewCZwO/qORMIBIIUA2IyOmAUsrvIh2QUzndjBNeqjhiwWY&#13;&#10;qWQbsKTccwC9oKIkTJIXQOqpAgBzFjJ6SnHW0gAAAABJRU5ErkJggg==" xlink:actuate="onLoad"/>
<text x="832" y="28" clip-path="url(#clipPath112)" fill="black" stroke="none" xml:space="preserve">BRepMesh_FaceDiscret</text>
<line clip-path="url(#clipPath113)" fill="none" x1="794" x2="982" y1="36" y2="36" stroke="rgb(39,76,114)"/>
</g>
<g stroke-linecap="butt" font-size="11" fill="rgb(69,69,69)" font-family="'Segoe UI'" stroke-dasharray="5,5" stroke="rgb(69,69,69)" stroke-width="1.1">
<line clip-path="url(#clipPath114)" fill="none" x1="219" x2="375" y1="564" y2="622"/>
<image x="23" y="598" clip-path="url(#clipPath115)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="42" y="611" clip-path="url(#clipPath116)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;T, BaseClass-&gt;BRepMesh_SweepLineMeshAlgo</text>
<line clip-path="url(#clipPath117)" fill="none" x1="367" x2="375" y1="622" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath117)" fill="none" x1="375" x2="369" y1="622" y2="617" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="661" x2="913" y1="981" y2="876"/>
<image x="829" y="909" clip-path="url(#clipPath118)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="848" y="922" clip-path="url(#clipPath119)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath120)" fill="none" x1="908" x2="913" y1="881" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath120)" fill="none" x1="913" x2="905" y1="876" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="672" x2="672" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="672" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="466" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="405" y1="438" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="405" x2="405" y1="438" y2="420" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="757" x2="757" y1="1281" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="757" x2="885" y1="1241" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="885" x2="885" y1="1241" y2="1223" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="538" x2="253" y1="981" y2="876"/>
<image x="128" y="903" clip-path="url(#clipPath124)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="147" y="916" clip-path="url(#clipPath125)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath126)" fill="none" x1="261" x2="253" y1="876" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath126)" fill="none" x1="253" x2="259" y1="876" y2="881" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="214" x2="214" y1="466" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="214" x2="405" y1="438" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="405" x2="405" y1="438" y2="420" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="600" x2="447" y1="564" y2="622"/>
<image x="435" y="598" clip-path="url(#clipPath127)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="454" y="611" clip-path="url(#clipPath128)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;T, BaseClass-&gt;BRepMesh_DelaunayBaseMeshAlgo</text>
<line clip-path="url(#clipPath129)" fill="none" x1="452" x2="447" y1="617" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath129)" fill="none" x1="447" x2="455" y1="622" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1414" y2="1397" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1397" y2="1397" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1397" y2="1379" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath130)" points=" 1009 1379 1013 1387 1005 1387" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath130)" points=" 1009 1379 1013 1387 1005 1387" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="428" x2="428" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="428" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1013" x2="1013" y1="1281" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1013" x2="885" y1="1241" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="885" x2="885" y1="1241" y2="1223" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="793" x2="734" y1="827" y2="827" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath131)" fill="none" x1="741" x2="734" y1="824" y2="827" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath131)" fill="none" x1="734" x2="741" y1="827" y2="830" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="218" x2="218" y1="778" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="218" x2="407" y1="738" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="407" x2="407" y1="738" y2="720" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="590" x2="590" y1="981" y2="876"/>
<image x="409" y="897" clip-path="url(#clipPath133)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="428" y="910" clip-path="url(#clipPath134)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath135)" fill="none" x1="593" x2="590" y1="883" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath135)" fill="none" x1="590" x2="587" y1="876" y2="883" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="520" x2="823" y1="376" y2="376" stroke="rgb(136,136,136)"/>
<text x="667" y="372" clip-path="url(#clipPath136)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath137)" fill="none" x1="816" x2="823" y1="379" y2="376" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath137)" fill="none" x1="823" x2="816" y1="376" y2="373" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="176" x2="176" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="176" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="896" x2="896" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="896" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="601" x2="601" y1="778" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="601" x2="407" y1="738" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="407" x2="407" y1="738" y2="720" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="406" x2="406" y1="322" y2="288" stroke="rgb(136,136,136)"/>
<polygon fill="white" clip-path="url(#clipPath138)" points=" 406 288 410 296 402 296" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath138)" points=" 406 288 410 296 402 296" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1399" x2="1399" y1="346" y2="288" stroke="rgb(136,136,136)"/>
<polygon fill="white" clip-path="url(#clipPath139)" points=" 1399 288 1403 296 1395 296" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath139)" points=" 1399 288 1403 296 1395 296" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="793" x2="734" y1="827" y2="827" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath131)" fill="none" x1="741" x2="734" y1="824" y2="827" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath131)" fill="none" x1="734" x2="741" y1="827" y2="830" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1297" x2="1165" y1="398" y2="398" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath140)" fill="none" x1="1172" x2="1165" y1="395" y2="398" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath140)" fill="none" x1="1165" x2="1172" y1="398" y2="401" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="176" x2="176" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="176" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="428" x2="428" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="428" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="672" x2="672" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="672" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="896" x2="896" y1="1125" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="896" x2="602" y1="1097" y2="1097" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="1097" y2="1079" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath121)" points=" 602 1079 606 1087 598 1087" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="757" x2="757" y1="1281" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="757" x2="885" y1="1241" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="885" x2="885" y1="1241" y2="1223" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1013" x2="1013" y1="1281" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1013" x2="885" y1="1241" y2="1241" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="885" x2="885" y1="1241" y2="1223" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath123)" points=" 885 1223 889 1231 881 1231" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="538" x2="253" y1="981" y2="876"/>
<image x="128" y="903" clip-path="url(#clipPath124)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="147" y="916" clip-path="url(#clipPath125)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath126)" fill="none" x1="261" x2="253" y1="876" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath126)" fill="none" x1="253" x2="259" y1="876" y2="881" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="590" x2="590" y1="981" y2="876"/>
<image x="409" y="897" clip-path="url(#clipPath133)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="428" y="910" clip-path="url(#clipPath134)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath135)" fill="none" x1="593" x2="590" y1="883" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath135)" fill="none" x1="590" x2="587" y1="876" y2="883" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="661" x2="913" y1="981" y2="876"/>
<image x="829" y="909" clip-path="url(#clipPath118)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="848" y="922" clip-path="url(#clipPath119)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;RangeSplitter</text>
<line clip-path="url(#clipPath120)" fill="none" x1="908" x2="913" y1="881" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath120)" fill="none" x1="913" x2="905" y1="876" y2="876" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="828" x2="409" y1="108" y2="190" stroke="rgb(136,136,136)"/>
<text x="580" y="136" clip-path="url(#clipPath141)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath142)" fill="none" x1="415" x2="409" y1="186" y2="190" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath142)" fill="none" x1="409" x2="416" y1="190" y2="192" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="966" x2="1393" y1="108" y2="190" stroke="rgb(136,136,136)"/>
<text x="1141" y="142" clip-path="url(#clipPath143)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath144)" fill="none" x1="1386" x2="1393" y1="192" y2="190" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath144)" fill="none" x1="1393" x2="1387" y1="190" y2="186" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="406" x2="406" y1="322" y2="288" stroke="rgb(136,136,136)"/>
<polygon fill="white" clip-path="url(#clipPath138)" points=" 406 288 410 296 402 296" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath138)" points=" 406 288 410 296 402 296" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="214" x2="214" y1="466" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="214" x2="405" y1="438" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="405" x2="405" y1="438" y2="420" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="520" x2="823" y1="376" y2="376" stroke="rgb(136,136,136)"/>
<text x="667" y="372" clip-path="url(#clipPath136)" fill="black" stroke="none" xml:space="preserve">&lt;&lt;use&gt;&gt;</text>
<line clip-path="url(#clipPath137)" fill="none" x1="816" x2="823" y1="379" y2="376" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath137)" fill="none" x1="823" x2="816" y1="376" y2="373" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="602" y1="466" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="602" x2="405" y1="438" y2="438" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="405" x2="405" y1="438" y2="420" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath122)" points=" 405 420 409 428 401 428" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="600" x2="447" y1="564" y2="622"/>
<image x="435" y="598" clip-path="url(#clipPath127)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="454" y="611" clip-path="url(#clipPath128)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;T, BaseClass-&gt;BRepMesh_DelaunayBaseMeshAlgo</text>
<line clip-path="url(#clipPath129)" fill="none" x1="452" x2="447" y1="617" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath129)" fill="none" x1="447" x2="455" y1="622" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="219" x2="375" y1="564" y2="622"/>
<image x="23" y="598" clip-path="url(#clipPath115)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVR42mNkIALo&#13;&#10;ebX+R+Zf2lbNCGMzEWMASENTbQhWOaIM2HD85v+65jUMCbF2DGSDvuWH/2PzDkGb&#13;&#10;CWlgoouzSQLEOBunF2jmbJCL8LoKl7NB4shRB6Nh4mAv4HI2TBzZFbAkDBJHNgTD&#13;&#10;2eguQncBjI1iCD5vYaPxasYWBsi2E6WZWAAAvauBMFaKJxwAAAAASUVORK5CYII=" xlink:type="simple" xlink:actuate="onLoad" height="16" preserveAspectRatio="none" xlink:show="embed"/>
<text x="42" y="611" clip-path="url(#clipPath116)" fill="black" stroke="none" xml:space="preserve">RangeSplitter-&gt;T, BaseClass-&gt;BRepMesh_SweepLineMeshAlgo</text>
<line clip-path="url(#clipPath117)" fill="none" x1="367" x2="375" y1="622" y2="622" stroke-dasharray="none"/>
<line clip-path="url(#clipPath117)" fill="none" x1="375" x2="369" y1="622" y2="617" stroke-dasharray="none"/>
<line clip-path="url(#clipPath114)" fill="none" x1="218" x2="218" y1="778" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="218" x2="407" y1="738" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="407" x2="407" y1="738" y2="720" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="601" x2="601" y1="778" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="601" x2="407" y1="738" y2="738" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="407" x2="407" y1="738" y2="720" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath132)" points=" 407 720 411 728 403 728" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1414" y2="1397" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1397" y2="1397" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<line clip-path="url(#clipPath114)" fill="none" x1="1009" x2="1009" y1="1397" y2="1379" stroke-dasharray="none" stroke="rgb(136,136,136)"/>
<polygon fill="white" stroke-dasharray="none" clip-path="url(#clipPath130)" points=" 1009 1379 1013 1387 1005 1387" stroke="none"/>
<polygon fill="none" stroke-dasharray="none" clip-path="url(#clipPath130)" points=" 1009 1379 1013 1387 1005 1387" stroke="rgb(136,136,136)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -3103,15 +3103,44 @@ Learn more about SALOME platform on http://www.salome-platform.org
The algorithm of shape triangulation is provided by the functionality of *BRepMesh_IncrementalMesh* class, which adds a triangulation of the shape to its topological data structure. This triangulation is used to visualize the shape in shaded mode.
~~~~~
const Standard_Real aRadius = 10.0;
const Standard_Real aHeight = 25.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
const Standard_Real aLinearDeflection = 0.01;
const Standard_Real anAngularDeflection = 0.5;
#include <IMeshData_Status.hxx>
#include <IMeshTools_Parameters.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
BRepMesh_IncrementalMesh aMesh(aShape, aLinearDeflection, Standard_False, anAngularDeflection);
Standard_Boolean meshing_explicit_parameters()
{
const Standard_Real aRadius = 10.0;
const Standard_Real aHeight = 25.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
const Standard_Real aLinearDeflection = 0.01;
const Standard_Real anAngularDeflection = 0.5;
BRepMesh_IncrementalMesh aMesher (aShape, aLinearDeflection, Standard_False, anAngularDeflection, Standard_True);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
Standard_Boolean meshing_imeshtools_parameters()
{
const Standard_Real aRadius = 10.0;
const Standard_Real aHeight = 25.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
IMeshTools_Parameters aMeshParams;
aMeshParams.Deflection = 0.01;
aMeshParams.Angle = 0.5;
aMeshParams.Relative = Standard_False;
aMeshParams.InParallel = Standard_True;
aMeshParams.MinSize = Precision::Confusion();
aMeshParams.InternalVerticesMode = Standard_True;
aMeshParams.ControlSurfaceDeflection = Standard_True;
BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
~~~~~
The default meshing algorithm *BRepMesh_IncrementalMesh* has two major options to define triangulation -- linear and angular deflections.
@@ -3122,9 +3151,9 @@ At the second step, the faces are tessellated. Linear deflection limits the dist
@figure{/user_guides/modeling_algos/images/modeling_algos_image056.png,"Deflection parameters of BRepMesh_IncrementalMesh algorithm",420}
Linear deflection limits the distance between triangles and the face interior.
There are additional options to control behavior of the meshing of face interior: *DeflectionInterior* and *AngleInterior*. *DeflectionInterior* limits the distance between triangles and the face interior. *AngleInterior* (used for tessellation of B-spline faces only) limits the angle between normals (N1, N2 and N3 in the picture) in the nodes of every link of the triangle. There is an exception for the links along the face boundary edges, "Angular Deflection" is used for them during edges discretization.
@figure{/user_guides/modeling_algos/images/modeling_algos_image057.png,"Linear deflection",420}
@figure{/user_guides/modeling_algos/images/modeling_algos_image057.png,"Linear and angular interior deflections",420}
Note that if a given value of linear deflection is less than shape tolerance then the algorithm will skip this value and will take into account the shape tolerance.
@@ -3138,6 +3167,100 @@ Meshing covers a shape with a triangular mesh. Other than hidden line removal, y
You can obtain information on the shape by first exploring it. To access triangulation of a face in the shape later, use *BRepTool::Triangulation*. To access a polygon, which is the approximation of an edge of the face, use *BRepTool::PolygonOnTriangulation*.
@subsection occt_modalg_11_3 BRepMesh Architecture
@subsubsection occt_modalg_11_3_1 Goals
The main goals of the chosen architecture are:
* Remove tight connections between data structures, auxiliary tools and algorithms to create an extensible solution, easy for maintenance and improvements;
* Separate the code among several functional units responsible for specific operation for the sake of simplification of debugging and readability;
* Introduce new data structures enabling the possibility to manipulate a discrete model of a particular entity (edge, wire, face) in order to perform computations locally instead of processing the entire model;
* Implement a new triangulation algorithm replacing the existing functionality that contains overcomplicated solutions that need to be moved to the upper level. In addition, provide the possibility to change the algorithm depending on surface type (initially to speed up meshing of planes).
@subsubsection occt_modalg_11_3_2 General workflow
@figure{/user_guides/modeling_algos/images/modeling_algos_mesh_001.svg,"General workflow of BRepMesh component",500}
Generally, the workflow of the component can be divided into six parts:
* **Creation of model data structure**: source *TopoDS_Shape* passed to algorithm is analyzed and exploded into faces and edges. The reflection corresponding to each topological entity is created in the data model. Note that underlying algorithms use the data model as input and access it via a common interface which allows creating a custom data model with necessary dependencies between particular entities (see the paragraph "Data model interface");
* **Discretize edges 3D & 2D curves**: 3D curve as well as an associated set of 2D curves of each model edge is discretized in order to create a coherent skeleton used as a base in face meshing process. If an edge of the source shape already contains polygonal data which suits the specified parameters, it is extracted from the shape and stored in the model as is. Each edge is processed separately, the adjacency is not taken into account;
* **Heal discrete model**: the source *TopoDS_Shape* can contain problems, such as open wires or self-intersections, introduced during design, exchange or modification of model. In addition, some problems like self-intersections can be introduced by roughly discretized edges. This stage is responsible for analysis of a discrete model in order to detect and repair problems or to refuse further processing of a model part in case if a problem cannot be solved;
* **Preprocess discrete model**: defines actions specific to the implemented approach to be performed before meshing of faces. By default, this operation iterates over model faces, checks the consistency of existing triangulations and cleans topological faces and adjacent edges from polygonal data in case of inconsistency or marks a face of the discrete model as not required for the computation;
* **Discretize faces**: represents the core part performing mesh generation for a particular face based on 2D discrete data. This operation caches polygonal data associated with face edges in the data model for further processing and stores the generated mesh to *TopoDS_Face*;
* **Postprocess discrete model**: defines actions specific for the implemented approach to be performed after meshing of faces. By default, this operation stores polygonal data obtained at the previous stage to *TopoDS_Edge* objects of the source model.
@subsubsection occt_modalg_11_3_3 Common interfaces
The component structure contains two units: <i>IMeshData</i> (see Data model interface) and <i>IMeshTools</i>, defining common interfaces for the data model and algorithmic tools correspondingly. Class *IMeshTools_Context* represents a connector between these units. The context class caches the data model as well as the tools corresponding to each of six stages of the workflow mentioned above and provides methods to call the corresponding tool safely (designed similarly to *IntTools_Context* in order to keep consistency with OCCT core tools). All stages, except for the first one, use the data model as input and perform a specific action on the entire structure. Thus, API class *IMeshTools_ModelAlgo* is defined in order to unify the interface of tools manipulating the data model. Each tool supposed to process the data model should inherit this interface enabling the possibility to cache it in context. In contrast to others, the model builder interface is defined by another class *IMeshTools_ModelBuilder* due to a different meaning of the stage. The entry point starting the entire workflow is represented by *IMeshTools_MeshBuilder*.
The default implementation of *IMeshTools_Context* is given in *BRepMesh_Context* class initializing the context by instances of default algorithmic tools.
The factory interface *IMeshTools_MeshAlgoFactory* gives the possibility to change the triangulation algorithm for a specific surface. The factory returns an instance of the triangulation algorithm via *IMeshTools_MeshAlgo* interface depending on the type of surface passed as parameter. It is supposed to be used at the face discretization stage.
The default implementation of AlgoFactory is given in *BRepMesh_MeshAlgoFactory* returning algorithms of different complexity chosen according to the passed surface type. In its turn, it is used as the initializer of *BRepMesh_FaceDiscret* algorithm representing the starter of face discretization stage.
@figure{/user_guides/modeling_algos/images/modeling_algos_mesh_002.svg,"Interface describing entry point to meshing workflow",500}
Remaining interfaces describe auxiliary tools:
* *IMeshTools_CurveTessellator*: provides a common interface to the algorithms responsible for creation of discrete polygons on 3D and 2D curves as well as tools for extraction of existing polygons from *TopoDS_Edge* allowing to obtain discrete points and the corresponding parameters on curve regardless of the implementation details (see examples of usage of derived classes *BRepMesh_CurveTessellator*, *BRepMesh_EdgeTessellationExtractor* in *BRepMesh_EdgeDiscret*);
* *IMeshTools_ShapeExplorer*: the last two interfaces represent visitor design pattern and are intended to separate iteration over elements of topological shape (edges and faces) from the operations performed on a particular element;
* *IMeshTools_ShapeVisitor*: provides a common interface for operations on edges and faces of the target topological shape. It can be used in couple with *IMeshTools_ShapeExplorer*. The default implementation available in *BRepMesh_ShapeVisitor* performs initialization of the data model. The advantage of such approach is that the implementation of *IMeshTools_ShapeVisitor* can be changed according to the specific data model whereas the shape explorer implementation remains the same.
@subsubsection occt_modalg_11_3_4 Create model data structure
The data structures intended to keep discrete and temporary data required by underlying algorithms are created at the first stage of the meshing procedure. Generally, the model represents dependencies between entities of the source topological shape suitable for the target task.
#### Data model interface
Unit <i>IMeshData</i> provides common interfaces specifying the data model API used on different stages of the entire workflow. Dependencies and references of the designed interfaces are given in the figure below. A specific interface implementation depends on the target application which allows the developer to implement different models and use custom low-level data structures, e.g. different collections, either <i>NCollection</i> or STL. *IMeshData_Shape* is used as the base class for all data structures and tools keeping the topological shape in order to avoid possible copy-paste.
The default implementation of interfaces is given in <i>BRepMeshData</i> unit. The main aim of the default data model is to provide features performing discretization of edges in a parallel mode. Thus, curve, pcurve and other classes are based on STL containers and smart-pointers as far as <i>NCollection</i> does not provide thread-safety for some cases (e.g. *NCollection_Sequence*). In addition, it closely reflects topology of the source shape, i.e. the number of edges in the data model is equal to the number of edges in the source model; each edge contains a set of pcurves associated with its adjacent faces which allows creation of discrete polygons for all pcurves or the 3D curve of a particular edge in a separate thread.
**Advantages**:
In case of necessity, the data model (probably with algorithms for its processing) can be easily substituted by another implementation supporting another kind of dependencies between elements.
An additional example of a different data model is the case when it is not required to create a mesh with discrete polygons synchronized between adjacent faces, i.e. in case of necessity to speed up creation of a rough per-face tessellation used for visualization or quick computation only (the approach used in *XDEDRAW_Props*).
@figure{/user_guides/modeling_algos/images/modeling_algos_mesh_003.svg,"Common API of data model",500}
#### Collecting data model
At this stage the data model is filled by entities according to the topological structure of the source shape. A default implementation of the data model is given in <i>BRepMeshData</i> unit and represents the model as two sets: a set of edges and a set of faces. Each face consists of one or several wires, the first of which always represents the outer wire, while others are internal. In its turn, each wire depicts the ordered sequence of oriented edges. Each edge is characterized by a single 3D curve and zero (in case of free edge) or more 2D curves associated with faces adjacent to this edge. Both 3D and 2D curves represent a set of pairs point-parameter defined in 3D and 2D space of the reference face correspondingly. An additional difference between a curve and a pcurve is that the latter has a reference to the face it is defined for.
Model filler algorithm is represented by *BRepMesh_ShapeVisitor* class creating the model as a reflection to topological shape with help of *BRepMesh_ShapeExplorer* performing iteration over edges and faces of the target shape. Note that the algorithm operates on a common interface of the data model and creates a structure without any knowledge about the implementation details and underlying data structures. The entry point to collecting functionality is *BRepMesh_ModelBuilder* class.
@subsubsection occt_modalg_11_3_5 Discretize edges 3D & 2D curves
At this stage only the edges of the data model are considered. Each edge is processed separately (with the possibility to run processing in multiple threads). The edge is checked for existing polygonal data. In case if at least one representation exists and suits the meshing parameters, it is recuperated and used as reference data for tessellation of the whole set of pcurves as well as 3D curve assigned to the edge (see *BRepMesh_EdgeTessellationExtractor*). Otherwise, a new tessellation algorithm is created and used to generate the initial polygon (see *BRepMesh_CurveTessellator*) and the edge is marked as outdated. In addition, the model edge is updated by deflection as well as recomputed same range, same parameter and degeneracy parameters. See *BRepMesh_EdgeDiscret* for implementation details.
<i>IMeshData</i> unit defines interface *IMeshData_ParametersListArrayAdaptor*, which is intended to adapt arbitrary data structures to the *NCollection_Array1* container API. This solution is made to use both *NCollection_Array1* and *IMeshData_Curve* as the source for *BRepMesh_EdgeParameterProvider* tool intended to generate a consistent parametrization taking into account the same parameter property.
@subsubsection occt_modalg_11_3_6 Heal discrete model
In general, this stage represents a set of operations performed on the entire discrete model in order to resolve inconsistencies due to the problems caused by design, translation or rough discretization. A different sequence of operations can be performed depending on the target triangulation algorithm, e.g. there are different approaches to process self-intersections either to amplify edges discretization by decreasing the target precision or to split links at the intersection points. At this stage the whole set of edges is considered in aggregate and their adjacency is taken into account. A default implementation of the model healer is given in *BRepMesh_ModelHealer* which performs the following actions:
* Iterates over model faces and checks their wires for consistency, i.e. whether the wires are closed and do not contain self-intersections. The data structures are designed free of collisions, thus it is possible to run processing in a parallel mode;
* Forcibly connects the ends of adjacent edges in the parametric space, closing gaps between possible disconnected parts. The aim of this operation is to create a correct discrete model defined relatively to the parametric space of the target face taking into account connectivity and tolerances of 3D space only. This means that no specific computations are made to determine U and V tolerance;
* Registers intersections on edges forming the face shape. Two solutions are possible in order to resolve self-intersection:
* Decrease deflection of a particular edge and update its discrete model. After that the workflow "intersection check amplification" is repeated up to 5 times. As the result, target edges contain a finer tessellation and meshing continues or the face is marked by *IMeshData_SelfIntersectingWire* status and refused from further processing;
* Split target edges by intersection point and synchronize the updated polygon with curve and remaining pcurves associated to each edge. This operation presents a more robust solution comparing to the amplification procedure with a guaranteed result, but it is more difficult for implementation from the point of view of synchronization functionality.
@subsubsection occt_modalg_11_3_7 Preprocess discrete model
This stage implements actions to be performed before meshing of faces. Depending on target goals it can be changed or omitted. By default, *BRepMesh_ModelPreProcessor* implements the functionality checking topological faces for consistency of existing triangulation, i.e.: consistency with the target deflection parameter; indices of nodes referenced by triangles do not exceed the number of nodes stored in a triangulation. If the face fails some checks, it is cleaned from triangulation and its adjacent edges are cleaned from existing polygons. This does not affect a discrete model and does not require any recomputation as the model keeps tessellations for the whole set of edges despite consistency of their polygons.
@subsubsection occt_modalg_11_3_8 Discretize faces
Discretization of faces is the general part of meshing algorithm. At this stage edges tessellation data obtained and processed on previous steps is used to form contours of target faces and passed as input to the triangulation algorithm. Default implementation is provided by *BRepMesh_FaceDiscret* class which represents a starter for triangulation algorithm. It iterates over faces available in the data model, creates an instance of the triangulation algorithm according to the type of surface associated with each face via *IMeshTools_MeshAlgoFactory* and executes it. Each face is processed separately, thus it is possible to process faces in a parallel mode. The class diagram of face discretization is given in the figure below.
@figure{/user_guides/modeling_algos/images/modeling_algos_mesh_004.svg,"Class diagram of face discrete stage",300}
In general, face meshing algorithms have the following structure:
* *BRepMesh_BaseMeshAlgo* implements *IMeshTools_MeshAlgo* interface and the base functionality for inherited algorithms. The main goal of this class is to initialize an instance of *BRepMesh_DataStructureOfDelaun* as well as auxiliary data structures suitable for nested algorithms using face model data passed as input parameter. Despite implementation of triangulation algorithm this structure is currently supposed as common for OCCT. However, the user is free to implement a custom algorithm and supporting data structure accessible via *IMeshTools_MeshAlgo* interface, e.g. to connect a 3-rd party meshing tool that does not support *TopoDS_Shape* out of box. For this, such structure provides the possibility to distribute connectors to various algorithms in the form of plugins;
* *BRepMesh_DelaunayBaseMeshAlgo* and *BRepMesh_SweepLineMeshAlgo* classes implement core meshing functionality operating directly on an instance of *BRepMesh_DataStructureOfDelaun*. The algorithms represent mesh generation tools adding new points from the data structure to the final mesh;
* *BRepMesh_NodeInsertionMeshAlgo* class represents a wrapper intended to extend the algorithm inherited from *BRepMesh_BaseMeshAlgo* to enable the functionality generating surface nodes and inserting them into the structure. On this level, an instance of the classification tool is created and can be used to accept-reject internal nodes. In addition, computations necessary for scaling UV coordinates of points relatively to the range specified for the corresponding direction are performed. As far as both triangulation algorithms work on static data provided by the structure, new nodes are added at the initialization stage. Surface nodes are generated by an auxiliary tool called range splitter and passed as template parameter (see Range splitter);
* Classes *BRepMesh_DelaunayNodeInsertionMeshAlgo* and *BRepMesh_SweepLineNodeInsertionMeshAlgo* implement algorithm-specific functionality related to addition of internal nodes supplementing functionality provided by *BRepMesh_NodeInsertionMeshAlgo*;
* *BRepMesh_DelaunayDeflectionControlMeshAlgo* extends functionality of *BRepMesh_DelaunayNodeInsertionMeshAlgo* by additional procedure controlling deflection of generated triangles.
#### Range splitter
Range splitter tools provide functionality to generate internal surface nodes defined within the range computed using discrete model data. The base functionality is provided by *BRepMesh_DefaultRangeSplitter* which can be used without modifications in case of planar surface. The default splitter does not generate any internal node.
*BRepMesh_ConeRangeSplitter*, *BRepMesh_CylinderRangeSplitter* and *BRepMesh_SphereRangeSplitter* are specializations of the default splitter intended for quick generation of internal nodes for the corresponding type of analytical surface.
*BRepMesh_UVParamRangeSplitter* implements base functionality taking discretization points of face border into account for node generation. Its successors BRepMesh_TorusRangeSplitter and *BRepMesh_NURBSRangeSplitter* extend the base functionality for toroidal and NURBS surfaces correspondingly.
@subsubsection occt_modalg_11_3_9 Postprocess discrete model
This stage implements actions to be performed after meshing of faces. Depending on target goals it can be changed or omitted. By default, *BRepMesh_ModelPostProcessor* commits polygonal data stored in the data model to *TopoDS_Edge*.
@section occt_modalg_defeaturing 3D Model Defeaturing
@@ -3315,3 +3438,312 @@ Here are the few examples of defeaturing of the model containing boxes with blen
<td>@figure{/user_guides/modeling_algos/images/modeling_algos_rf_im029.png,"Result",220}</td></td>
</tr>
</table>
@section occt_modalg_makeperiodic 3D Model Periodicity
Open CASCADE Technology provides tools for making an arbitrary 3D model (or just shape) periodic in 3D space in the specified directions.
Periodicity of the shape means that the shape can be repeated in any periodic direction any number of times without creation of the new geometry or splits.
The idea of this algorithm is to make the shape look similarly on the opposite sides or on the period bounds of periodic directions.
It does not mean that the opposite sides of the shape will be mirrored. It just means that the opposite sides of the shape should be split by each other and obtain the same geometry on opposite sides.
Such approach will allow repeating the shape, i.e. translating the copy of a shape on the period, without creation of new geometry because there will be no coinciding parts of different dimension.
For better understanding of what periodicity means lets create a simple prism and make it periodic.
The following draw script creates the L-shape prism with extensions 10x5x10:
~~~~
polyline p 0 0 0 0 0 10 5 0 10 5 0 5 10 0 5 10 0 0 0 0 0
mkplane f p
prism s f 0 5 0
~~~~
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im001.png,"Shape to make periodic",220}
Making this shape periodic in X, Y and Z directions with the periods matching the shape's extensions should make the splits of negative X and Z sides of the shape. The shape is already similar on opposite sides of Y directions, thus no new splits is expected.
Here is the shape after making it periodic:
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im002.png,"Periodic shape",220}
And here is the repetition of the shape once in X and Z directions:
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im003.png,"Repeated shape",220}
The OCCT Shape Periodicity tools also allows making the shape periodic with the period not matching the shape's extensions. Let's make the shape periodic with 11, 6 and 11 for X, Y, Z periods accordingly.
Such values of periods mean that there will be a gap between repeated shapes, and since during repetition the opposite sides do not touch the shape will not be split at all.
Here is the repetition of the shape once in X and Z directions:
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im004.png,"Repeated shape",220}
As expected, the shape is not split and the repeated elements do not touch.
If necessary the algorithm will trim the shape to fit into the requested period by splitting it with the planes limiting the shape's requested periods.
E.g. let's make the L-shape periodic only in X direction with the period 2 starting at X parameter 4:
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im005.png,"Periodic trimmed shape",220}
@subsection occt_modalg_makeperiodic_how_it_works How the shape is made periodic
For making the shape periodic in certain direction the algorithm performs the following steps:
* Creates the copy of the shape and moves it on the period into negative side of the requested direction;
* Splits the negative side of the shape by the moved copy, ensuring copying of the geometry from positive side to negative;
* Creates the copy of the shape (with already split negative side) and moves it on the period into the positive side of the requested direction;
* Splits the positive side of the shape by the moved copy, ensuring copying of the geometry from negative side to positive.
Repeated copying of the geometry ensures that the corner edges of the periodic shape will have the same geometry on opposite sides of all periodic directions.
Thus, in the periodic shape the geometry from positive side of the shape is always copied on the negative side of periodic directions.
@subsection occt_modalg_makeperiodic_association Opposite shapes association
The algorithm also associates the identical (or twin) shapes located on the opposite sides of the periodic shape. By the construction, the twin shapes should always have the same geometry and distanced from each other on the period.
It is possible that the shape does not have any twins. It means that when repeating this shape will not touch the opposite side of the shape. In the example when the periods of the shape are grater than its extensions, non of the sub-shapes has a twin.
@subsection occt_modalg_makeperiodic_repetition Periodic shape repetition
The algorithm also provides the methods to repeat the periodic shape in periodic directions. To repeat shape the algorithm makes the requested number of copies of the shape and translates them one by one on the time * period value.
After all copies are made and translated they are glued to have valid shape.
The subsequent repetitions are performed on the repeated shape, thus e.g. repeating the shape two times in any periodic direction will create result containing three shapes (original plus two copies).
Single subsequent repetition in any direction will result already in 6 shapes.
The repetitions can be cleared and started over.
@subsection occt_modalg_makeperiodic_history History support
The algorithm supports the history of shapes modifications, thus it is possible to track how the shapes have been changed to make it periodic and what new shapes have been created during repetitions.
Both split history and history of periodic shape repetition are available here. Note, that all repeated shapes are stored as generated into the history.
*BRepTools_History* is used for history support.
@subsection occt_modalg_makeperiodic_errors Errors/Warnings
The algorithm supports the Error/Warning reporting system which allows obtaining the extended overview of the errors and warning occurred during the operation.
As soon as any error appears the algorithm stops working. The warnings allow continuing the job, informing the user that something went wrong.
The algorithm returns the following alerts:
* *BOPAlgo_AlertNoPeriodicityRequired* - Error alert is given if no periodicity has been requested in any direction;
* *BOPAlgo_AlertUnableToTrim* - Error alert is given if the trimming of the shape for fitting it into requested period has failed;
* *BOPAlgo_AlertUnableToMakeIdentical* - Error alert is given if splitting of the shape by its moved copies has failed;
* *BOPAlgo_AlertUnableToRepeat* - Warning alert is given if the gluing of the repeated shapes has failed.
For more information on the error/warning reporting system please see the chapter @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide.
@subsection occt_modalg_makeperiodic_usage Usage
The algorithm is implemented in the class *BOPAlgo_MakePeriodic*.
Here is the example of its usage on the API level:
~~~~
TopoDS_Shape aShape = ...; // The shape to make periodic
Standard_Boolean bMakeXPeriodic = ...; // Flag for making or not the shape periodic in X direction
Standard_Real aXPeriod = ...; // X period for the shape
Standard_Boolean isXTrimmed = ...; // Flag defining whether it is necessary to trimming
// the shape to fit to X period
Standard_Real aXFirst = ...; // Start of the X period
// (really necessary only if the trimming is requested)
Standard_Boolean bRunParallel = ...; // Parallel processing mode or single
BOPAlgo_MakePeriodic aPeriodicityMaker; // Periodicity maker
aPeriodicityMaker.SetShape(aShape); // Set the shape
aPeriodicityMaker.MakeXPeriodic(bMakePeriodic, aXPeriod); // Making the shape periodic in X direction
aPeriodicityMaker.SetTrimmed(isXTrimmed, aXFirst); // Trim the shape to fit X period
aPeriodicityMaker.SetRunParallel(bRunParallel); // Set the parallel processing mode
aPeriodicityMaker.Perform(); // Performing the operation
if (aPeriodicityMaker.HasErrors()) // Check for the errors
{
// errors treatment
Standard_SStream aSStream;
aPeriodicityMaker.DumpErrors(aSStream);
return;
}
if (aPeriodicityMaker.HasWarnings()) // Check for the warnings
{
// warnings treatment
Standard_SStream aSStream;
aPeriodicityMaker.DumpWarnings(aSStream);
}
const TopoDS_Shape& aPeriodicShape = aPeriodicityMaker.Shape(); // Result periodic shape
aPeriodicityMaker.XRepeat(2); // Making repetitions
const TopoDS_Shape& aRepeat = aPeriodicityMaker.RepeatedShape(); // Getting the repeated shape
aPeriodicityMaker.ClearRepetitions(); // Clearing the repetitions
~~~~
Please note, that the class is based on the options class *BOPAlgo_Options*, which provides the following options for the algorithm:
* Error/Warning reporting system;
* Parallel processing mode.
The other options of the base class are not supported here and will have no effect.
All the history information obtained during the operation is stored into *BRepTools_History* object and available through *History()* method:
~~~~
// Get the history object
const Handle(BRepTools_History)& BOPAlgo_MakePeriodic::History();
~~~~
For the usage of the MakePeriodic algorithm on the Draw level the following commands have been implemented:
* **makeperiodic**
* **repeatshape**
* **periodictwins**
* **clearrepetitions**
For more details on the periodicity commands please refer the @ref occt_draw_makeperiodic "Periodicity commands" of the Draw test harness user guide.
To track the history of a shape modification during MakePeriodic operation the @ref occt_draw_hist "standard history commands" can be used.
To have possibility to access the error/warning shapes of the operation use the *bdrawwarnshapes* command before running the algorithm (see command usage in the @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide).
@subsection occt_modalg_makeperiodic_examples Examples
Imagine that you need to make the drills in the plate on the same distance from each other. To model this process it is necessary to make a lot of cylinders (simulating the drills) and cut these cylinders from the plate.
With the periodicity tool, the process looks very simple:
~~~~
# create plate 100 x 100
box plate -50 -50 0 100 100 1
# create a single drill with radius 1
pcylinder drill 1 1
# locate the drill in the left corner
ttranslate drill -48 -48 0
# make the drill periodic with 4 as X and Y periods, so the distance between drills will be 2
makeperiodic drill drill -x 4 -trim -50 -y 4 -trim -50
# repeat the drill to fill the plate, in result we get net of 25 x 25 drills
repeatshape drills -x 24 -y 24
# cut the drills from the plate
bcut result plate drills
~~~~
@figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im006.png,"Plate with drills",220}
@section occt_modalg_makeconnected Making touching shapes connected
Open CASCADE Technology provides tools for making the same-dimensional touching shapes connected (or glued), i.e. for making the coinciding geometries topologically shared among shapes.
To make the shapes connected they are glued by the means of @ref occt_algorithms_7 "General Fuse algorithm". The option BOPAlgo_GlueShift is used, thus if the input shapes have been interfering the algorithm will be unable to recognize this.
Making the group of shapes connected can be useful e.g. before meshing the group. It will allow making the resulting mesh conformal.
The algorithm for making the shapes connected is implemented in the class *BOPAlgo_MakeConnected*.
@subsection occt_modalg_makeconnected_materials Material association
In frames of this tool the input shapes are called materials, and each input shape has a unique material.
After making the shapes connected, the border elements of the input shapes are associated with the shapes to which they belong. At that, the orientation of the border elements in the shape is taken into account.
The associations are made for the following types:
* For input SOLIDS the resulting FACES are associated with the input solids;
* For input FACES the resulting EDGES are associated with the input faces;
* For input EDGES the resulting VERTICES are associated with the input edges.
The association process is called the material association. It allows finding the coinciding elements for the opposite input shapes. These elements will be associated to at least two materials (one on the positive side of the shape, the other - on negative).
For obtaining the material information the following methods should be used
* *MaterialsOnPositiveSide()* - returns the original shapes (materials) located on the positive side of the given shape (i.e. with FORWARD orientation);
* *MaterialsOnNegativeSide()* - returns the original shapes (materials) located on the negative side of the given shape (i.e. with REVERSED orientation);
~~~~
// Returns the original shapes which images contain the given shape with FORWARD orientation.
const TopTools_ListOfShape& BOPAlgo_MakeConnected::MaterialsOnPositiveSide(const TopoDS_Shape& theS)
// Returns the original shapes which images contain the given shape with REVERSED orientation.
const TopTools_ListOfShape& BOPAlgo_MakeConnected::MaterialsOnNegativeSide(const TopoDS_Shape& theS)
~~~~
@subsection occt_modalg_makeconnected_makeperiodic Making connected shape periodic
The tool provides possibility to make the connected shape @ref occt_modalg_makeperiodic "periodic".
Since by making the shape periodic it ensures that the geometry of coinciding shapes on the opposite sides will be the same it allows reusing the mesh of the shape for its periodic twins.
After making the shape periodic the material associations are updated to correspond to the actual state of the result shape. Repetition of the periodic shape is also possible from here. Material associations are not going to be lost.
@subsection occt_modalg_makeconnected_history History support
The algorithm supports history of shapes modifications during the operation. Additionally to standard history method provided by *BRepTools_History* and used here as a history tool, the algorithm also provides the method to track the back connection - from resulting shapes to the input ones.
The method is called *GetOrigins()*:
~~~~
// Returns the list of original shapes from which the current shape has been created.
const TopTools_ListOfShape& BOPAlgo_MakeConnected::GetOrigins(const TopoDS_Shape& theS);
~~~~
Both Gluing history and history of making the shape periodic and periodic shape repetition are available here. Note, that all repeated shapes are stored as generated into the history.
@subsection occt_modalg_makeconnected_errors Errors/Warnings
The algorithm supports the Error/Warning reporting system which allows obtaining the extended overview of the errors and warning occurred during the operation.
As soon as any error appears the algorithm stops working. The warnings allow continuing the job, informing the user that something went wrong.
The algorithm returns the following alerts:
* *BOPAlgo_AlertTooFewArguments* - error alert is given on the attempt to run the algorithm without the arguments;
* *BOPAlgo_AlertMultiDimensionalArguments* - error alert is given on the attempt to run the algorithm on multi-dimensional arguments;
* *BOPAlgo_AlertUnableToGlue* - error alert is given if the gluer algorithm is unable to glue the given arguments;
* *BOPAlgo_AlertUnableToMakePeriodic* - warning alert is given if the periodicity maker is unable to make the connected shape periodic with given options;
* *BOPAlgo_AlertShapeIsNotPeriodic* - warning alert is given on the attempt to repeat the shape before making it periodic.
For more information on the error/warning reporting system please see the chapter @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide.
@subsection occt_modalg_makeconnected_usage Usage
Here is the example of usage of the *BOPAlgo_MakePeriodic* algorithm on the API level:
~~~~
TopTools_ListOfShape anArguments = ...; // Shapes to make connected
Standard_Boolean bRunParallel = ...; // Parallel processing mode
BOPAlgo_MakeConnected aMC; // Tool for making the shapes connected
aMC.SetArguments(anArguments); // Set the shapes
aMC.SetRunParallel(bRunParallel); // Set parallel processing mode
aMC.Perform(); // Perform the operation
if (aMC.HasErrors()) // Check for the errors
{
// errors treatment
Standard_SStream aSStream;
aMC.DumpErrors(aSStream);
return;
}
if (aMC.HasWarnings()) // Check for the warnings
{
// warnings treatment
Standard_SStream aSStream;
aMC.DumpWarnings(aSStream);
}
const TopoDS_Shape& aGluedShape = aMC.Shape(); // Connected shape
// Checking material associations
TopAbs_ShapeEnum anElemType = ...; // Type of border element
TopExp_Explorer anExp(anArguments.First(), anElemType);
for (; anExp.More(); anExp.Next())
{
const TopoDS_Shape& anElement = anExp.Current();
const TopTools_ListOfShape& aNegativeM = aMC.MaterialsOnNegativeSide(anElement);
const TopTools_ListOfShape& aPositiveM = aMC.MaterialsOnPositiveSide(anElement);
}
// Making the connected shape periodic
BOPAlgo_MakePeriodic::PeriodicityParams aParams = ...; // Options for periodicity of the connected shape
aMC.MakePeriodic(aParams);
// Shape repetition after making it periodic
// Check if the shape has been made periodic successfully
if (aMC.PeriodicityTool().HasErrors())
{
// Periodicity maker error treatment
}
// Shape repetition in periodic directions
aMC.RepeatShape(0, 2);
const TopoDS_Shape& aShape = aMC.PeriodicShape(); // Periodic and repeated shape
~~~~
Please note, that the class is based on the options class *BOPAlgo_Options*, which provides the following options for the algorithm:
* Error/Warning reporting system;
* Parallel processing mode.
The other options of the base class are not supported here and will have no effect.
All the history information obtained during the operation is stored into *BRepTools_History* object and available through *History()* method:
~~~~
// Get the history object
const Handle(BRepTools_History)& BOPAlgo_MakeConnected::History();
~~~~
For the usage of the MakeConnected algorithm on the Draw level the following commands have been implemented:
* **makeconnected**
* **cmaterialson**
* **cmakeperiodic**
* **crepeatshape**
* **cperiodictwins**
* **cclearrepetitions**
For more details on the connexity commands please refer the @ref occt_draw_makeconnected "MakeConnected commands" of the Draw test harness user guide.
To track the history of a shape modification during MakeConnected operation the @ref occt_draw_hist "standard history commands" can be used.
To have possibility to access the error/warning shapes of the operation use the *bdrawwarnshapes* command before running the algorithm (see command usage in the @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide).

View File

@@ -1793,12 +1793,11 @@ Create facet attributes.
Handle(Graphic3d_AspectFillArea3d) aFaceAspect = new Graphic3d_AspectFillArea3d();
Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NOM_BRASS);
Graphic3d_MaterialAspect aGoldMaterial (Graphic3d_NOM_GOLD);
aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID);
aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID_WIREFRAME);
aFaceAspect->SetInteriorColor (aMyColor);
aFaceAspect->SetDistinguishOn ();
aFaceAspect->SetFrontMaterial (aGoldMaterial);
aFaceAspect->SetBackMaterial (aBrassMaterial);
aFaceAspect->SetEdgeOn();
~~~~~
Create text attributes.

View File

@@ -46,6 +46,7 @@
#pragma comment(lib, "TKSTEP.lib")
#pragma comment(lib, "TKStl.lib")
#pragma comment(lib, "TKVrml.lib")
#pragma comment(lib, "TKLCAF.lib")
//! Auxiliary tool for converting C# string into UTF-8 string.
static TCollection_AsciiString toAsciiString (String^ theString)

View File

@@ -54,6 +54,7 @@
#pragma comment(lib, "TKSTEP.lib")
#pragma comment(lib, "TKStl.lib")
#pragma comment(lib, "TKVrml.lib")
#pragma comment(lib, "TKLCAF.lib")
#pragma comment(lib, "D3D9.lib")

View File

@@ -0,0 +1,68 @@
cmake_minimum_required(VERSION 3.2)
project(glfw-occt-demo)
set(CMAKE_CXX_STANDARD 11)
set(APP_VERSION_MAJOR 1)
set(APP_VERSION_MINOR 0)
set(APP_TARGET glfwocct)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
file(GLOB SOURCES
*.h
*.cpp
)
source_group ("Headers" FILES
GlfwOcctView.h
GlfwOcctWindow.h)
source_group ("Sources" FILES
GlfwOcctView.cpp
GlfwOcctWindow.cpp
main.cpp)
# OpenGL
find_package(OpenGL REQUIRED)
# 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
TKernel
TKService
TKV3d
TKOpenGl
TKBRep
TKGeomBase
TKGeomAlgo
TKG3d
TKG2d
TKTopAlgo
TKPrim
)
# glfw
find_package(glfw3 REQUIRED)
if (glfw3_FOUND)
message (STATUS "Using glfw3 ${glfw3_VERSION}" )
INCLUDE_DIRECTORIES(${GLFW_INCLUDE_DIRS})
LINK_DIRECTORIES(${GLFW_LIBRARY_DIRS})
else()
message (STATUS "glfw3 is not found." )
endif()
add_executable(${APP_TARGET} ${SOURCES})
target_link_libraries(
${APP_TARGET}
${OpenCASCADE_LIBS}
glfw
${OPENGL_LIBRARIES}
)

View File

@@ -0,0 +1,324 @@
// 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 "GlfwOcctView.h"
#include <AIS_Shape.hxx>
#include <Aspect_Handle.hxx>
#include <Aspect_DisplayConnection.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <iostream>
#include <GLFW/glfw3.h>
// ================================================================
// Function : GlfwOcctView
// Purpose :
// ================================================================
GlfwOcctView::GlfwOcctView()
: myCurAction3d (CurAction3d_Nothing),
myToRedraw (true)
{
}
// ================================================================
// Function : ~GlfwOcctView
// Purpose :
// ================================================================
GlfwOcctView::~GlfwOcctView()
{
}
// ================================================================
// Function : toView
// Purpose :
// ================================================================
GlfwOcctView* GlfwOcctView::toView (GLFWwindow* theWin)
{
return static_cast<GlfwOcctView*>(glfwGetWindowUserPointer (theWin));
}
// ================================================================
// Function : errorCallback
// Purpose :
// ================================================================
void GlfwOcctView::errorCallback (int theError, const char* theDescription)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error") + theError + ": " + theDescription, Message_Fail);
}
// ================================================================
// Function : run
// Purpose :
// ================================================================
void GlfwOcctView::run()
{
initWindow (800, 600, "glfw occt");
initViewer();
initDemoScene();
if (myView.IsNull())
{
return;
}
myView->MustBeResized();
myOcctWindow->Map();
mainloop();
cleanup();
}
// ================================================================
// Function : initWindow
// Purpose :
// ================================================================
void GlfwOcctView::initWindow (int theWidth, int theHeight, const char* theTitle)
{
glfwSetErrorCallback (GlfwOcctView::errorCallback);
glfwInit();
const bool toAskCoreProfile = true;
if (toAskCoreProfile)
{
glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 3);
#if defined (__APPLE__)
glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
myOcctWindow = new GlfwOcctWindow (theWidth, theHeight, theTitle);
glfwSetWindowUserPointer (myOcctWindow->getGlfwWindow(), this);
// window callback
glfwSetWindowSizeCallback (myOcctWindow->getGlfwWindow(), GlfwOcctView::onResizeCallback);
glfwSetFramebufferSizeCallback (myOcctWindow->getGlfwWindow(), GlfwOcctView::onFBResizeCallback);
// mouse callback
glfwSetScrollCallback (myOcctWindow->getGlfwWindow(), GlfwOcctView::onMouseScrollCallback);
glfwSetMouseButtonCallback (myOcctWindow->getGlfwWindow(), GlfwOcctView::onMouseButtonCallback);
glfwSetCursorPosCallback (myOcctWindow->getGlfwWindow(), GlfwOcctView::onMouseMoveCallback);
}
// ================================================================
// Function : initViewer
// Purpose :
// ================================================================
void GlfwOcctView::initViewer()
{
if (myOcctWindow.IsNull()
|| myOcctWindow->getGlfwWindow() == nullptr)
{
return;
}
Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (myOcctWindow->GetDisplay(), false);
Handle(V3d_Viewer) aViewer = new V3d_Viewer (aGraphicDriver);
aViewer->SetDefaultLights();
aViewer->SetLightOn();
aViewer->SetDefaultTypeOfView (V3d_PERSPECTIVE);
aViewer->ActivateGrid (Aspect_GT_Rectangular, Aspect_GDM_Lines);
myView = aViewer->CreateView();
myView->SetImmediateUpdate (false);
myView->SetWindow (myOcctWindow, myOcctWindow->NativeGlContext());
myView->ChangeRenderingParams().ToShowStats = true;
myContext = new AIS_InteractiveContext (aViewer);
}
// ================================================================
// Function : initDemoScene
// Purpose :
// ================================================================
void GlfwOcctView::initDemoScene()
{
if (myContext.IsNull())
{
return;
}
myView->TriedronDisplay (Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_WIREFRAME);
gp_Ax2 anAxis;
anAxis.SetLocation (gp_Pnt (0.0, 0.0, 0.0));
Handle(AIS_Shape) aBox = new AIS_Shape (BRepPrimAPI_MakeBox (anAxis, 50, 50, 50).Shape());
myContext->Display (aBox, AIS_Shaded, 0, false);
anAxis.SetLocation (gp_Pnt (25.0, 125.0, 0.0));
Handle(AIS_Shape) aCone = new AIS_Shape (BRepPrimAPI_MakeCone (anAxis, 25, 0, 50).Shape());
myContext->Display (aCone, AIS_Shaded, 0, false);
TCollection_AsciiString aGlInfo;
{
TColStd_IndexedDataMapOfStringString aRendInfo;
myView->DiagnosticInformation (aRendInfo, Graphic3d_DiagnosticInfo_Basic);
for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aRendInfo); aValueIter.More(); aValueIter.Next())
{
if (!aGlInfo.IsEmpty()) { aGlInfo += "\n"; }
aGlInfo += TCollection_AsciiString(" ") + aValueIter.Key() + ": " + aValueIter.Value();
}
}
Message::DefaultMessenger()->Send (TCollection_AsciiString("OpenGL info:\n") + aGlInfo, Message_Info);
}
// ================================================================
// Function : mainloop
// Purpose :
// ================================================================
void GlfwOcctView::mainloop()
{
while (!glfwWindowShouldClose (myOcctWindow->getGlfwWindow()))
{
// glfwPollEvents() for continuous rendering (immediate return if there are no new events)
// and glfwWaitEvents() for rendering on demand (something actually happened in the viewer)
//glfwPollEvents();
glfwWaitEvents();
if (!myView.IsNull())
{
if (myView->IsInvalidated())
{
myView->Redraw();
}
else if (myToRedraw)
{
myView->RedrawImmediate();
}
myToRedraw = false;
}
}
}
// ================================================================
// Function : cleanup
// Purpose :
// ================================================================
void GlfwOcctView::cleanup()
{
if (!myView.IsNull())
{
myView->Remove();
}
if (!myOcctWindow.IsNull())
{
myOcctWindow->Close();
}
glfwTerminate();
}
// ================================================================
// Function : onResize
// Purpose :
// ================================================================
void GlfwOcctView::onResize (int theWidth, int theHeight)
{
if (theWidth != 0
&& theHeight != 0
&& !myView.IsNull())
{
myView->Window()->DoResize();
myView->MustBeResized();
myView->Invalidate();
myView->Redraw();
//myToRedraw = true;
}
}
// ================================================================
// Function : onMouseScroll
// Purpose :
// ================================================================
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;
}
// ================================================================
// Function : onMouseButton
// Purpose :
// ================================================================
void GlfwOcctView::onMouseButton (int theButton, int theAction, int theMods)
{
if (myView.IsNull()) { return; }
const Graphic3d_Vec2i aPos = myOcctWindow->CursorPosition();
if (theAction != GLFW_PRESS)
{
myCurAction3d = CurAction3d_Nothing;
return;
}
myMouseMin = aPos;
myMouseMax = aPos;
switch (theButton)
{
case GLFW_MOUSE_BUTTON_RIGHT:
{
myCurAction3d = CurAction3d_DynamicRoation;
myView->StartRotation (aPos.x(), aPos.y());
break;
}
case GLFW_MOUSE_BUTTON_MIDDLE:
{
myCurAction3d = CurAction3d_DynamicPanning;
break;
}
}
}
// ================================================================
// Function : onMouseMove
// Purpose :
// ================================================================
void GlfwOcctView::onMouseMove (int thePosX, int thePosY)
{
if (myView.IsNull()) { return; }
switch (myCurAction3d)
{
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;
}
}
}

125
samples/glfw/GlfwOcctView.h Normal file
View File

@@ -0,0 +1,125 @@
// 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 _GlfwOcctView_Header
#define _GlfwOcctView_Header
#include "GlfwOcctWindow.h"
#include <AIS_InteractiveContext.hxx>
#include <V3d_View.hxx>
//! Sample class creating 3D Viewer within GLFW window.
class GlfwOcctView
{
public:
enum CurAction3d
{
CurAction3d_Nothing,
CurAction3d_DynamicZooming,
CurAction3d_DynamicPanning,
CurAction3d_DynamicRoation
};
public:
//! Default constructor.
GlfwOcctView();
//! Destructor.
~GlfwOcctView();
//! Main application entry point.
void run();
private:
//! Create GLFW window.
void initWindow (int theWidth, int theHeight, const char* theTitle);
//! Create 3D Viewer.
void initViewer();
//! Fill 3D Viewer with a DEMO items.
void initDemoScene();
//! Application event loop.
void mainloop();
//! Clean up before .
void cleanup();
//! @name GLWF callbacks
private:
//! Window resize event.
void onResize (int theWidth, int theHeight);
//! Mouse scroll event.
void onMouseScroll (double theOffsetX, double theOffsetY);
//! Mouse click event.
void onMouseButton (int theButton, int theAction, int theMods);
//! Mouse move event.
void onMouseMove (int thePosX, int thePosY);
//! @name GLWF callbacks (static functions)
private:
//! GLFW callback redirecting messages into Message::DefaultMessenger().
static void errorCallback (int theError, const char* theDescription);
//! Wrapper for glfwGetWindowUserPointer() returning this class instance.
static GlfwOcctView* toView (GLFWwindow* theWin);
//! Window resize callback.
static void onResizeCallback (GLFWwindow* theWin, int theWidth, int theHeight)
{ toView(theWin)->onResize (theWidth, theHeight); }
//! Frame-buffer resize callback.
static void onFBResizeCallback (GLFWwindow* theWin, int theWidth, int theHeight)
{ toView(theWin)->onResize (theWidth, theHeight); }
//! Mouse scroll callback.
static void onMouseScrollCallback (GLFWwindow* theWin, double theOffsetX, double theOffsetY)
{ toView(theWin)->onMouseScroll (theOffsetX, theOffsetY); }
//! Mouse click callback.
static void onMouseButtonCallback (GLFWwindow* theWin, int theButton, int theAction, int theMods)
{ toView(theWin)->onMouseButton (theButton, theAction, theMods); }
//! Mouse move callback.
static void onMouseMoveCallback (GLFWwindow* theWin, double thePosX, double thePosY)
{ toView(theWin)->onMouseMove ((int )thePosX, (int )thePosY); }
private:
Handle(GlfwOcctWindow) myOcctWindow;
Handle(V3d_View) myView;
Handle(AIS_InteractiveContext) myContext;
CurAction3d myCurAction3d;
Graphic3d_Vec2i myMouseMin;
Graphic3d_Vec2i myMouseMax;
bool myToRedraw;
};
#endif // _GlfwOcctView_Header

View File

@@ -0,0 +1,161 @@
// 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 "GlfwOcctWindow.h"
#if defined (__APPLE__)
#undef Handle // avoid name collisions in macOS headers
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#elif defined (_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#else
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
// ================================================================
// Function : GlfwOcctWindow
// Purpose :
// ================================================================
GlfwOcctWindow::GlfwOcctWindow (int theWidth, int theHeight, const TCollection_AsciiString& theTitle)
: myGlfwWindow (glfwCreateWindow (theWidth, theHeight, theTitle.ToCString(), NULL, NULL)),
myXLeft (0),
myYTop (0),
myXRight (0),
myYBottom(0)
{
if (myGlfwWindow != nullptr)
{
int aWidth = 0, aHeight = 0;
glfwGetWindowPos (myGlfwWindow, &myXLeft, &myYTop);
glfwGetWindowSize(myGlfwWindow, &aWidth, &aHeight);
myXRight = myXLeft + aWidth;
myYBottom = myYTop + aHeight;
#if !defined(_WIN32) && !defined(__APPLE__)
myDisplay = new Aspect_DisplayConnection (glfwGetX11Display());
#endif
}
}
// ================================================================
// Function : Close
// Purpose :
// ================================================================
void GlfwOcctWindow::Close()
{
if (myGlfwWindow != nullptr)
{
glfwDestroyWindow (myGlfwWindow);
myGlfwWindow = nullptr;
}
}
// ================================================================
// Function : NativeHandle
// Purpose :
// ================================================================
Aspect_Drawable GlfwOcctWindow::NativeHandle() const
{
#if defined (__APPLE__)
return (Aspect_Drawable)glfwGetCocoaWindow (myGlfwWindow);
#elif defined (_WIN32)
return (Aspect_Drawable)glfwGetWin32Window (myGlfwWindow);
#else
return (Aspect_Drawable)glfwGetX11Window (myGlfwWindow);
#endif
}
// ================================================================
// Function : NativeGlContext
// Purpose :
// ================================================================
Aspect_RenderingContext GlfwOcctWindow::NativeGlContext() const
{
#if defined (__APPLE__)
return (NSOpenGLContext*)glfwGetNSGLContext (myGlfwWindow);
#elif defined (_WIN32)
return glfwGetWGLContext (myGlfwWindow);
#else
return glfwGetGLXContext (myGlfwWindow);
#endif
}
// ================================================================
// Function : IsMapped
// Purpose :
// ================================================================
Standard_Boolean GlfwOcctWindow::IsMapped() const
{
return glfwGetWindowAttrib (myGlfwWindow, GLFW_VISIBLE) != 0;
}
// ================================================================
// Function : Map
// Purpose :
// ================================================================
void GlfwOcctWindow::Map() const
{
glfwShowWindow (myGlfwWindow);
}
// ================================================================
// Function : Unmap
// Purpose :
// ================================================================
void GlfwOcctWindow::Unmap() const
{
glfwHideWindow (myGlfwWindow);
}
// ================================================================
// Function : DoResize
// Purpose :
// ================================================================
Aspect_TypeOfResize GlfwOcctWindow::DoResize() const
{
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;
}
return Aspect_TOR_UNKNOWN;
}
// ================================================================
// Function : CursorPosition
// Purpose :
// ================================================================
Graphic3d_Vec2i GlfwOcctWindow::CursorPosition() const
{
Graphic3d_Vec2d aPos;
glfwGetCursorPos (myGlfwWindow, &aPos.x(), &aPos.y());
return Graphic3d_Vec2i ((int )aPos.x(), (int )aPos.y());
}

View File

@@ -0,0 +1,115 @@
// 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 _GlfwOcctWindow_Header
#define _GlfwOcctWindow_Header
#include <Aspect_DisplayConnection.hxx>
#include <Aspect_RenderingContext.hxx>
#include <Aspect_Window.hxx>
#include <Graphic3d_Vec.hxx>
#include <TCollection_AsciiString.hxx>
struct GLFWwindow;
//! GLFWwindow wrapper implementing Aspect_Window interface.
class GlfwOcctWindow : public Aspect_Window
{
DEFINE_STANDARD_RTTI_INLINE(GlfwOcctWindow, Aspect_Window)
public:
//! Main constructor.
GlfwOcctWindow (int theWidth, int theHeight, const TCollection_AsciiString& theTitle);
//! Close the window.
virtual ~GlfwOcctWindow() { Close(); }
//! Close the window.
void Close();
//! Return X Display connection.
const Handle(Aspect_DisplayConnection)& GetDisplay() const { return myDisplay; }
//! Return GLFW window.
GLFWwindow* getGlfwWindow() { return myGlfwWindow; }
//! Return native OpenGL context.
Aspect_RenderingContext NativeGlContext() const;
//! Return cursor position.
Graphic3d_Vec2i CursorPosition() const;
public:
//! Returns native Window handle
virtual Aspect_Drawable NativeHandle() const Standard_OVERRIDE;
//! Returns parent of native Window handle.
virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return 0; }
//! Applies the resizing to the window <me>
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE;
//! Returns True if the window <me> is opened and False if the window is closed.
virtual Standard_Boolean IsMapped() const Standard_OVERRIDE;
//! Apply the mapping change to the window <me> and returns TRUE if the window is mapped at screen.
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
//! Opens the window <me>.
virtual void Map() const Standard_OVERRIDE;
//! Closes the window <me>.
virtual void Unmap() const Standard_OVERRIDE;
virtual void Position (Standard_Integer& theX1, Standard_Integer& theY1,
Standard_Integer& theX2, Standard_Integer& theY2) const Standard_OVERRIDE
{
theX1 = myXLeft;
theX2 = myXRight;
theY1 = myYTop;
theY2 = myYBottom;
}
//! Returns The Window RATIO equal to the physical WIDTH/HEIGHT dimensions.
virtual Standard_Real Ratio() const Standard_OVERRIDE
{
return Standard_Real (myXRight - myXLeft) / Standard_Real (myYBottom - myYTop);
}
//! Return window size.
virtual void Size (Standard_Integer& theWidth, Standard_Integer& theHeight) const Standard_OVERRIDE
{
theWidth = myXRight - myXLeft;
theHeight = myYBottom - myYTop;
}
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
protected:
Handle(Aspect_DisplayConnection) myDisplay;
GLFWwindow* myGlfwWindow;
Standard_Integer myXLeft;
Standard_Integer myYTop;
Standard_Integer myXRight;
Standard_Integer myYBottom;
};
#endif // _GlfwOcctWindow_Header

37
samples/glfw/main.cpp Normal file
View File

@@ -0,0 +1,37 @@
// 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 "GlfwOcctView.h"
int main (int, char**)
{
GlfwOcctView anApp;
try
{
anApp.run();
}
catch (const std::runtime_error& theError)
{
std::cerr << theError.what() << std::endl;
return EXIT_FAILURE;
}
return 0;
}

4
samples/glfw/readme.md Normal file
View File

@@ -0,0 +1,4 @@
A sample demonstrating usage of OCCT 3D Viewer within a window created using GLFW.
Platforms: Windows, macOS, Linux
Required: glfw

View File

@@ -116,7 +116,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\$(VCFMT)\bin/ImportExport.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\..\win32\$(VCFMT)\lib;$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -158,7 +158,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\$(VCFMT)\bin/ImportExport.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\..\win64\$(VCFMT)\lib;$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -199,7 +199,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\$(VCFMT)\bind/ImportExport.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\..\win32\$(VCFMT)\libd;$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -241,7 +241,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;mfcsample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\$(VCFMT)\bind/ImportExport.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\..\..\win64\$(VCFMT)\libd;$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

View File

@@ -115,7 +115,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\$(VCFMT)\bind/mfcsample.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -158,7 +158,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\$(VCFMT)\bind/mfcsample.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -202,7 +202,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win32\$(VCFMT)\bin/mfcsample.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -246,7 +246,7 @@
<ResourceOutputFileName>$(IntDir)%(Filename).res</ResourceOutputFileName>
</ResourceCompile>
<Link>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>TKVCAF.lib;TKVrml.lib;TKStl.lib;TKBrep.lib;TKIGES.lib;TKShHealing.lib;TKStep.lib;TKXSBase.lib;TKBool.lib;TKCAF.lib;TKCDF.lib;TKernel.lib;TKFeat.lib;TKFillet.lib;TKG2d.lib;TKG3d.lib;TKGeomAlgo.lib;TKGeomBase.lib;TKHLR.lib;TKMath.lib;TKOffset.lib;TKPrim.lib;TKService.lib;TKTopAlgo.lib;TKMesh.lib;TKV3d.lib;TKOpenGl.lib;TKLCAF.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../../../win64\$(VCFMT)\bin/mfcsample.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(CSF_OCCTLibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

View File

@@ -14,9 +14,9 @@ Requirements for building sample:
* Android NDK r9d or newer
* Apache Ant 1.9.4 or higher
* OCCT compiled under Android platform and placed in directories:
* occt/libs/armeabi-v7a/*.so and occt/inc/*.hxx (libraries and include files of OCCT install)
* android/assets/opencascade/shared/Shaders/* (Shaders folder of OCCT install: /share/opencascade/resources/Shaders)
* 3rdparty/include/freetype2/*, 3rdparty/include/FreeImage.h and 3rdparty/libs/armeabi-v7a/libFreeImage.so and 3rdparty/libs/armeabi-v7a/libfreetype.so
* occt/libs/armeabi-v7a/\*.so and occt/inc/\*.hxx (libraries and include files of OCCT install)
* android/assets/opencascade/shared/Shaders/\* (Shaders folder of OCCT install: /share/opencascade/resources/Shaders)
* 3rdparty/include/freetype2/\*, 3rdparty/include/FreeImage.h and 3rdparty/libs/armeabi-v7a/libFreeImage.so and 3rdparty/libs/armeabi-v7a/libfreetype.so
It is also possible to to correct OCCT.pri file an get resources from another tree of directories.

View File

@@ -44,13 +44,13 @@ unix {
win32 {
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bind
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/objd
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bind
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/objd
MOC_DIR = ./src
} else {
DEFINES += NDEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bin
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/obj
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bin
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/obj
MOC_DIR = ./src
}
LIBS = -L$$(QTDIR)/lib;$$(CSF_OCCTLibPath)

View File

@@ -58,14 +58,14 @@ unix {
win32 {
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bind
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/objd
MOC_DIR = ./win$(ARCH)/$(VCVER)/mocd
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bind
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/objd
MOC_DIR = ./win$$(ARCH)/$$(VCVER)/mocd
} else {
DEFINES += NDEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bin
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/obj
MOC_DIR = ./win$(ARCH)/$(VCVER)/moc
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bin
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/obj
MOC_DIR = ./win$$(ARCH)/$$(VCVER)/moc
}
LIBS = -L$$(QTDIR)/lib;$$(CSF_OCCTLibPath)
DEFINES += NO_COMMONSAMPLE_EXPORTS NO_IESAMPLE_EXPORTS
@@ -75,7 +75,7 @@ LIBS += -lTKernel -lTKMath -lTKService -lTKV3d -lTKOpenGl \
-lTKBRep -lTKIGES -lTKSTL -lTKVRML -lTKSTEP -lTKSTEPAttr -lTKSTEP209 \
-lTKSTEPBase -lTKGeomBase -lTKGeomAlgo -lTKG3d -lTKG2d \
-lTKXSBase -lTKShHealing -lTKHLR -lTKTopAlgo -lTKMesh -lTKPrim \
-lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset \
-lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset -lTKLCAF \
!exists($${RES_DIR}) {
win32 {

View File

@@ -61,14 +61,14 @@ unix {
win32 {
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bind
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/objd
MOC_DIR = ./win$(ARCH)/$(VCVER)/mocd
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bind
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/objd
MOC_DIR = ./win$$(ARCH)/$$(VCVER)/mocd
} else {
DEFINES += NDEBUG
DESTDIR = ./win$(ARCH)/$(VCVER)/bin
OBJECTS_DIR = ./win$(ARCH)/$(VCVER)/obj
MOC_DIR = ./win$(ARCH)/$(VCVER)/moc
DESTDIR = ./win$$(ARCH)/$$(VCVER)/bin
OBJECTS_DIR = ./win$$(ARCH)/$$(VCVER)/obj
MOC_DIR = ./win$$(ARCH)/$$(VCVER)/moc
}
LIBS = -L$$(QTDIR)/lib;$$(CSF_OCCTLibPath)
DEFINES += NO_COMMONSAMPLE_EXPORTS NO_IESAMPLE_EXPORTS
@@ -78,7 +78,7 @@ LIBS += -lTKernel -lTKMath -lTKService -lTKV3d -lTKOpenGl \
-lTKBRep -lTKIGES -lTKSTL -lTKVRML -lTKSTEP -lTKSTEPAttr -lTKSTEP209 \
-lTKSTEPBase -lTKGeomBase -lTKGeomAlgo -lTKG3d -lTKG2d \
-lTKXSBase -lTKShHealing -lTKHLR -lTKTopAlgo -lTKMesh -lTKPrim \
-lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset \
-lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset -lTKLCAF \
!exists($${RES_DIR}) {
win32 {

View File

@@ -277,7 +277,6 @@ blend result _model 2 _model_161
pload VISUALIZATION
vinit Driver1/Viewer1/View1
vsetcolorbg 200 200 255
vdisplay result
vdisplay -dispMode 1 result
vfit
vsetdispmode 1
vshowfaceboundary result 1
vaspects result -setFaceBoundaryDraw 1 -mostContinuity c2

View File

@@ -263,7 +263,6 @@ unifysamedom result p_1
pload VISUALIZATION
vinit Driver1/Viewer1/View1
vsetcolorbg 200 200 255
vdisplay result
vdisplay -dispMode 1 result
vfit
vsetdispmode 1
vshowfaceboundary result 1
vaspects result -setFaceBoundaryDraw 1

View File

@@ -57,9 +57,7 @@ bcommon res b9 c2
# show result
donly res
trotate res 0 0 0 0 0 1 90
vinit
vdisplay res
vsetdispmode 1
vshowfaceboundary res 1 255 255 255
vaspects -isoontriangulation 1
vinit View1
vdisplay -dispMode 1 res
vaspects res -setFaceBoundaryDraw 1 -setFaceBoundaryColor WHITE -isoontriangulation 1
vfit

View File

@@ -0,0 +1,285 @@
// Created on: 2018-12-12
// Created by: Olga SURYANINOVA
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <AIS_CameraFrustum.hxx>
#include <AIS_DisplayMode.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Select3D_SensitiveGroup.hxx>
#include <Select3D_SensitivePrimitiveArray.hxx>
#include <Select3D_SensitiveSegment.hxx>
#include <SelectMgr_EntityOwner.hxx>
IMPLEMENT_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
namespace
{
static const Standard_ShortReal THE_DEFAULT_TRANSPARENCY = 0.7f;
static const Quantity_Color THE_DEFAULT_COLOR = Quantity_NOC_WHITE;
}
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
AIS_CameraFrustum::AIS_CameraFrustum()
: myPoints (0, Graphic3d_Camera::FrustumVerticesNB)
{
myDrawer->SetLineAspect (new Prs3d_LineAspect (THE_DEFAULT_COLOR, Aspect_TOL_SOLID, 1.0));
Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect();
aShadingAspect->SetMaterial (Graphic3d_NOM_PLASTIC);
aShadingAspect->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
aShadingAspect->SetTransparency (THE_DEFAULT_TRANSPARENCY);
aShadingAspect->SetColor (THE_DEFAULT_COLOR);
myDrawer->SetShadingAspect (aShadingAspect);
myDrawer->SetTransparency (THE_DEFAULT_TRANSPARENCY);
SetDisplayMode (AIS_Shaded);
}
//=======================================================================
//function : AcceptDisplayMode
//purpose :
//=======================================================================
Standard_Boolean AIS_CameraFrustum::AcceptDisplayMode (const Standard_Integer theMode) const
{
return theMode == AIS_Shaded || theMode == AIS_WireFrame;
}
//=======================================================================
//function : SetCameraFrustum
//purpose :
//=======================================================================
void AIS_CameraFrustum::SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera)
{
if (theCamera.IsNull())
{
return;
}
theCamera->FrustumPoints (myPoints);
fillTriangles();
fillBorders();
SetToUpdate();
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void AIS_CameraFrustum::SetColor (const Quantity_Color& theColor)
{
AIS_InteractiveObject::SetColor (theColor);
myDrawer->ShadingAspect()->SetColor (theColor);
myDrawer->LineAspect()->SetColor (theColor);
}
//=======================================================================
//function : UnsetColor
//purpose :
//=======================================================================
void AIS_CameraFrustum::UnsetColor()
{
if (!HasColor())
{
return;
}
AIS_InteractiveObject::UnsetColor();
myDrawer->ShadingAspect()->SetColor (THE_DEFAULT_COLOR);
myDrawer->LineAspect()->SetColor (THE_DEFAULT_COLOR);
}
//=======================================================================
//function : UnsetColor
//purpose :
//=======================================================================
void AIS_CameraFrustum::UnsetTransparency()
{
myDrawer->ShadingAspect()->SetTransparency (0.0f);
myDrawer->SetTransparency (0.0f);
}
//=======================================================================
//function : fillTriangles
//purpose :
//=======================================================================
void AIS_CameraFrustum::fillTriangles()
{
if (myTriangles.IsNull())
{
const Standard_Integer aPlaneTriangleVertsNb = 2 * 3;
const Standard_Integer aPlanesNb = 3 * 2;
myTriangles = new Graphic3d_ArrayOfTriangles (Graphic3d_Camera::FrustumVerticesNB, aPlaneTriangleVertsNb * aPlanesNb);
myTriangles->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
// Triangles go in order (clockwise vertices traversing for correct normal):
// (0, 2, 1), (3, 1, 2)
const Standard_Integer aLookup1_clockwise[] = { 0, 1, 0, 1, 0, 1 };
const Standard_Integer aLookup2_clockwise[] = { 0, 0, 1, 1, 1, 0 };
// Triangles go in order (counterclockwise vertices traversing for correct normal):
// (1, 2, 0), (2, 1, 3)
const Standard_Integer aLookup1_anticlockwise[] = { 0, 1, 0, 1, 0, 1 };
const Standard_Integer aLookup2_anticlockwise[] = { 1, 0, 0, 0, 1, 1 };
Standard_Integer aShifts[] = { 0, 0, 0 };
// Planes go in order:
// LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
{
for (Standard_Integer i = 0; i < 2; ++i)
{
for (Standard_Integer aPntIter = 0; aPntIter < aPlaneTriangleVertsNb; ++aPntIter)
{
aShifts[aFaceIdx] = i;
if (i == 0)
{
aShifts[(aFaceIdx + 1) % 3] = aLookup1_clockwise[aPntIter];
aShifts[(aFaceIdx + 2) % 3] = aLookup2_clockwise[aPntIter];
}
else
{
aShifts[(aFaceIdx + 1) % 3] = aLookup1_anticlockwise[aPntIter];
aShifts[(aFaceIdx + 2) % 3] = aLookup2_anticlockwise[aPntIter];
}
Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
myTriangles->AddEdge (anIndex + 1);
}
}
}
}
for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
{
const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
myTriangles->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
}
}
//=======================================================================
//function : fillBorders
//purpose :
//=======================================================================
void AIS_CameraFrustum::fillBorders()
{
if (myBorders.IsNull())
{
const Standard_Integer aPlaneSegmVertsNb = 2 * 4;
const Standard_Integer aPlanesNb = 3 * 2;
myBorders = new Graphic3d_ArrayOfSegments (Graphic3d_Camera::FrustumVerticesNB, aPlaneSegmVertsNb * aPlanesNb);
myBorders->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
// Segments go in order:
// (0, 2), (2, 3), (3, 1), (1, 0)
const Standard_Integer aLookup1[] = { 0, 1, 1, 1, 1, 0, 0, 0 };
const Standard_Integer aLookup2[] = { 0, 0, 0, 1, 1, 1, 1, 0 };
Standard_Integer aShifts[] = { 0, 0, 0 };
// Planes go in order:
// LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
{
for (Standard_Integer i = 0; i < 2; ++i)
{
for (Standard_Integer aSegmVertIter = 0; aSegmVertIter < aPlaneSegmVertsNb; ++aSegmVertIter)
{
aShifts[aFaceIdx] = i;
aShifts[(aFaceIdx + 1) % 3] = aLookup1[aSegmVertIter];
aShifts[(aFaceIdx + 2) % 3] = aLookup2[aSegmVertIter];
Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
myBorders->AddEdge (anIndex + 1);
}
}
}
}
for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
{
const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
myBorders->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
}
}
//=======================================================================
//function : Compute
//purpose :
//=======================================================================
void AIS_CameraFrustum::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode)
{
thePrs->SetInfiniteState (true);
if (myTriangles.IsNull())
{
return;
}
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
switch (theMode)
{
case AIS_Shaded:
{
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
aGroup->AddPrimitiveArray (myTriangles);
}
Standard_FALLTHROUGH
case AIS_WireFrame:
{
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
aGroup->AddPrimitiveArray (myBorders);
break;
}
}
}
//=======================================================================
//function : ComputeSelection
//purpose :
//=======================================================================
void AIS_CameraFrustum::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
switch (theMode)
{
case SelectionMode_Edges:
{
Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (anOwner);
for (Standard_Integer anIter = 1; anIter <= myBorders->EdgeNumber(); anIter += 2)
{
aSensitiveEntity->Add (new Select3D_SensitiveSegment (anOwner, myBorders->Vertice (myBorders->Edge (anIter)), myBorders->Vertice(myBorders->Edge (anIter + 1))));
}
theSelection->Add (aSensitiveEntity);
break;
}
case SelectionMode_Volume:
{
Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (anOwner);
aSelArray->InitTriangulation (myTriangles->Attributes(), myTriangles->Indices(), TopLoc_Location());
theSelection->Add (aSelArray);
break;
}
}
}

View File

@@ -0,0 +1,85 @@
// Created on: 2018-12-12
// Created by: Olga SURYANINOVA
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _AIS_CameraFrustum_HeaderFile
#define _AIS_CameraFrustum_HeaderFile
#include <AIS_InteractiveObject.hxx>
class Graphic3d_ArrayOfSegments;
class Graphic3d_ArrayOfTriangles;
//! Presentation for drawing camera frustum.
//! Default configuration is built with filling and some transparency.
class AIS_CameraFrustum : public AIS_InteractiveObject
{
DEFINE_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
public:
//! Selection modes supported by this object
enum SelectionMode
{
SelectionMode_Edges = 0, //!< detect by edges (default)
SelectionMode_Volume = 1, //!< detect by volume
};
public:
//! Constructs camera frustum with default configuration.
Standard_EXPORT AIS_CameraFrustum();
//! Sets camera frustum.
Standard_EXPORT void SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera);
//! Setup custom color.
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
//! Restore default color.
Standard_EXPORT virtual void UnsetColor() Standard_OVERRIDE;
//! Restore transparency setting.
Standard_EXPORT virtual void UnsetTransparency() Standard_OVERRIDE;
//! Return true if specified display mode is supported.
Standard_EXPORT virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE;
protected:
//! Computes presentation of camera frustum.
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode) Standard_OVERRIDE;
//! Compute selection.
Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode) Standard_OVERRIDE;
private:
//! Fills triangles primitive array for camera frustum filling.
void fillTriangles();
//! Fills polylines primitive array for camera frustum borders.
void fillBorders();
protected:
NCollection_Array1<Graphic3d_Vec3d> myPoints; //!< Array of points
Handle(Graphic3d_ArrayOfTriangles) myTriangles; //!< Triangles for camera frustum filling
Handle(Graphic3d_ArrayOfSegments) myBorders; //!< Segments for camera frustum borders
};
#endif // _AIS_CameraFrustum_HeaderFile

View File

@@ -107,6 +107,10 @@ AIS_ColorScale::AIS_ColorScale()
myTextHeight (20)
{
SetDisplayMode (0);
myDrawer->SetupOwnShadingAspect();
myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (Quantity_NOC_WHITE);
}
//=======================================================================
@@ -458,15 +462,6 @@ void AIS_ColorScale::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
const Standard_Integer aBarTop = myYPos + myHeight - aTitleOffset - aBarYOffset;
const Standard_Integer aBarHeight = aBarTop - aBarBottom;
// draw title
if (!myTitle.IsEmpty())
{
drawText (Prs3d_Root::CurrentGroup (thePrs), myTitle,
myXPos + mySpacing,
aBarTop + aBarYOffset,
Graphic3d_VTA_BOTTOM);
}
TColStd_SequenceOfExtendedString aLabels;
if (myLabelType == Aspect_TOCSD_USER)
{
@@ -496,11 +491,27 @@ void AIS_ColorScale::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
aColorBreadth += aTextWidth;
}
// draw title
Handle(Graphic3d_Group) aLabelsGroup;
if (!myTitle.IsEmpty()
|| !aLabels.IsEmpty())
{
aLabelsGroup = thePrs->NewGroup();
aLabelsGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
}
if (!myTitle.IsEmpty())
{
drawText (aLabelsGroup, myTitle,
myXPos + mySpacing,
aBarTop + aBarYOffset,
Graphic3d_VTA_BOTTOM);
}
// draw colors
drawColorBar (thePrs, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
// draw Labels
drawLabels (thePrs, aLabels, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
drawLabels (aLabelsGroup, aLabels, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
}
//=======================================================================
@@ -627,7 +638,8 @@ void AIS_ColorScale::drawColorBar (const Handle(Prs3d_Presentation)& thePrs,
}
}
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
aGroup->AddPrimitiveArray (aTriangles);
const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE);
@@ -642,7 +654,7 @@ void AIS_ColorScale::drawColorBar (const Handle(Prs3d_Presentation)& thePrs,
//function : drawLabels
//purpose :
//=======================================================================
void AIS_ColorScale::drawLabels (const Handle(Prs3d_Presentation)& thePrs,
void AIS_ColorScale::drawLabels (const Handle(Graphic3d_Group)& theGroup,
const TColStd_SequenceOfExtendedString& theLabels,
const Standard_Integer theBarBottom,
const Standard_Integer theBarHeight,
@@ -716,14 +728,14 @@ void AIS_ColorScale::drawLabels (const Handle(Prs3d_Presentation)& thePrs,
Standard_Integer aPos2 = aNbLabels - 1 - i2;
if (aFilter && !(aPos1 % aFilter))
{
drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i1 + 1),
drawText (theGroup, theLabels.Value (i1 + 1),
anXLeft, anYBottom + Standard_Integer(i1 * aStepY + anAscent),
Graphic3d_VTA_CENTER);
aLast1 = i1;
}
if (aFilter && !(aPos2 % aFilter))
{
drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i2 + 1),
drawText (theGroup, theLabels.Value (i2 + 1),
anXLeft, anYBottom + Standard_Integer(i2 * aStepY + anAscent),
Graphic3d_VTA_CENTER);
aLast2 = i2;
@@ -746,7 +758,7 @@ void AIS_ColorScale::drawLabels (const Handle(Prs3d_Presentation)& thePrs,
if (i0 != -1)
{
drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i0 + 1),
drawText (theGroup, theLabels.Value (i0 + 1),
anXLeft, anYBottom + Standard_Integer(i0 * aStepY + anAscent),
Graphic3d_VTA_CENTER);
}
@@ -769,8 +781,8 @@ void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePrs,
aPrim->AddVertex (theX, theY, 0.0);
Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d (theColor, Aspect_TOL_SOLID, 1.0);
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
aGroup->SetPrimitivesAspect (anAspect);
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->SetGroupPrimitivesAspect (anAspect);
aGroup->AddPrimitiveArray (aPrim);
}
@@ -784,7 +796,6 @@ void AIS_ColorScale::drawText (const Handle(Graphic3d_Group)& theGroup,
const Graphic3d_VerticalTextAlignment theVertAlignment)
{
const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect();
theGroup->SetPrimitivesAspect (anAspect->Aspect());
theGroup->Text (theText,
gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()),
anAspect->Height(),

View File

@@ -406,7 +406,7 @@ private:
Standard_Integer computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const;
//! Draw labels.
void drawLabels (const Handle(Prs3d_Presentation)& thePrs,
void drawLabels (const Handle(Graphic3d_Group)& theGroup,
const TColStd_SequenceOfExtendedString& theLabels,
const Standard_Integer theBarBottom,
const Standard_Integer theBarHeight,

View File

@@ -27,6 +27,7 @@ public:
AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink)
: myIsHidden (false),
myHasOwnColor (false),
myHasOwnTransp(false),
myHasOwnWidth (false)
{
Link (theLink);
@@ -34,9 +35,15 @@ public:
bool IsHidden() const { return myIsHidden; }
void SetHidden (const bool theToHide) { myIsHidden = theToHide;}
bool HasOwnColor() const { return myHasOwnColor; }
void UnsetOwnColor() { myHasOwnColor = false; }
void SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = true; }
bool HasOwnTransparency() const { return myHasOwnTransp; }
void UnsetOwnTransparency() { myHasOwnTransp = false; }
void SetOwnTransparency (Standard_Real /*theTransp*/) { myHasOwnTransp = true; }
bool HasOwnWidth() const { return myHasOwnWidth; }
void UnsetOwnWidth() { myHasOwnWidth = false; }
void SetOwnWidth (const Standard_Real /*theWidth*/) { myHasOwnWidth = true; }
@@ -45,6 +52,7 @@ public: //! @name list of overridden properties
bool myIsHidden;
bool myHasOwnColor;
bool myHasOwnTransp;
bool myHasOwnWidth;
};

View File

@@ -77,6 +77,7 @@ AIS_ColoredShape::AIS_ColoredShape (const TopoDS_Shape& theShape)
myDrawer->SetFreeBoundaryAspect (myDrawer->LineAspect());
myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
myDrawer->SetSeenLineAspect (myDrawer->LineAspect());
myDrawer->SetFaceBoundaryAspect (myDrawer->LineAspect());
}
//=======================================================================
@@ -90,6 +91,7 @@ AIS_ColoredShape::AIS_ColoredShape (const Handle(AIS_Shape)& theShape)
myDrawer->SetFreeBoundaryAspect (myDrawer->LineAspect());
myDrawer->SetUnFreeBoundaryAspect(myDrawer->LineAspect());
myDrawer->SetSeenLineAspect (myDrawer->LineAspect());
myDrawer->SetFaceBoundaryAspect (myDrawer->LineAspect());
if (theShape->HasMaterial())
{
SetMaterial (theShape->Material());
@@ -185,6 +187,25 @@ void AIS_ColoredShape::SetCustomColor (const TopoDS_Shape& theShape,
LoadRecomputable (AIS_Shaded);
}
//=======================================================================
//function : SetCustomTransparency
//purpose :
//=======================================================================
void AIS_ColoredShape::SetCustomTransparency (const TopoDS_Shape& theShape,
Standard_Real theTransparency)
{
if (theShape.IsNull())
{
return;
}
const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
setTransparency (aDrawer, theTransparency);
aDrawer->SetOwnTransparency (theTransparency);
LoadRecomputable (AIS_WireFrame);
LoadRecomputable (AIS_Shaded);
}
//=======================================================================
//function : SetCustomWidth
//purpose :
@@ -198,7 +219,7 @@ void AIS_ColoredShape::SetCustomWidth (const TopoDS_Shape& theShape,
}
const Handle(AIS_ColoredDrawer)& aDrawer = CustomAspects (theShape);
setWidth (CustomAspects (theShape), theLineWidth);
setWidth (aDrawer, theLineWidth);
aDrawer->SetOwnWidth (theLineWidth);
LoadRecomputable (AIS_WireFrame);
LoadRecomputable (AIS_Shaded);
@@ -236,6 +257,10 @@ void AIS_ColoredShape::SetColor (const Quantity_Color& theColor)
{
aDrawer->WireAspect()->SetColor (theColor);
}
if (aDrawer->HasOwnFaceBoundaryAspect())
{
aDrawer->FaceBoundaryAspect()->SetColor (theColor);
}
}
}
@@ -266,6 +291,10 @@ void AIS_ColoredShape::SetWidth (const Standard_Real theLineWidth)
{
aDrawer->WireAspect()->SetWidth (theLineWidth);
}
if (aDrawer->HasOwnFaceBoundaryAspect())
{
aDrawer->FaceBoundaryAspect()->SetWidth (theLineWidth);
}
}
}
@@ -282,7 +311,12 @@ void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
LoadRecomputable (AIS_Shaded);
for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
{
const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
if (aDrawer->HasOwnTransparency())
{
continue;
}
if (aDrawer->HasOwnShadingAspect())
{
aDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
@@ -336,7 +370,7 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
//if (aDrawer->HasOwnMaterial()) continue;
if (aDrawer->HasOwnShadingAspect())
{
setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), Standard_False); // aDrawer->IsTransparent()
setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), aDrawer->HasOwnTransparency());
}
}
}
@@ -576,7 +610,7 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
const DataMapOfDrawerCompd& theDrawerClosedFaces,
const Standard_Integer theMode)
{
Handle(Graphic3d_Group) anOpenGroup, aClosedGroup;
Handle(Graphic3d_Group) anOpenGroup, aClosedGroup, anEdgesGroup;
for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType)
{
const Standard_Boolean isClosed = aShType == TopAbs_SHAPE;
@@ -630,7 +664,7 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
{
if (aShadedGroup.IsNull())
{
aShadedGroup = Prs3d_Root::NewGroup (thePrs);
aShadedGroup = thePrs->NewGroup();
aShadedGroup->SetClosed (isClosed);
}
aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
@@ -639,18 +673,15 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
if (aDrawer->FaceBoundaryDraw())
{
Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw);
if (!aBndSegments.IsNull())
if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw, aDrawer->FaceBoundaryUpperContinuity()))
{
if (aShadedGroup.IsNull())
if (anEdgesGroup.IsNull())
{
aShadedGroup = Prs3d_Root::NewGroup (thePrs);
aShadedGroup->SetClosed (isClosed);
anEdgesGroup = thePrs->NewGroup();
}
Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect();
aShadedGroup->SetPrimitivesAspect (aBoundaryAspect);
aShadedGroup->AddPrimitiveArray (aBndSegments);
anEdgesGroup->SetPrimitivesAspect (aDrawer->FaceBoundaryAspect()->Aspect());
anEdgesGroup->AddPrimitiveArray (aBndSegments);
}
}
}
@@ -705,13 +736,29 @@ Standard_Boolean AIS_ColoredShape::dispatchColors (const Handle(AIS_ColoredDrawe
{
const TopoDS_Shape& aFace = aFaceIter.Value();
Handle(AIS_ColoredDrawer) aFaceDrawer;
if (aFace.ShapeType() == TopAbs_FACE
&& theShapeDrawerMap.Find (aFace, aFaceDrawer)
&& aFaceDrawer->IsHidden())
if (aFace.ShapeType() != TopAbs_FACE
|| !theShapeDrawerMap.Find (aFace, aFaceDrawer))
{
continue;
}
if (aFaceDrawer->IsHidden())
{
isClosedShell = Standard_False;
break;
}
else if (aFaceDrawer->HasOwnShadingAspect()
&& aFaceDrawer->ShadingAspect()->Aspect()->AlphaMode() != Graphic3d_AlphaMode_Opaque)
{
if (aFaceDrawer->ShadingAspect()->Aspect()->AlphaMode() != Graphic3d_AlphaMode_BlendAuto
|| aFaceDrawer->ShadingAspect()->Aspect()->FrontMaterial().Alpha() < 1.0f
|| (aFaceDrawer->ShadingAspect()->Aspect()->Distinguish()
&& aFaceDrawer->ShadingAspect()->Aspect()->BackMaterial().Alpha() < 1.0f))
{
isClosedShell = Standard_False;
break;
}
}
}
}

View File

@@ -56,6 +56,10 @@ public: //! @name sub-shape aspects
Standard_EXPORT void SetCustomColor (const TopoDS_Shape& theShape,
const Quantity_Color& theColor);
//! Customize transparency of specified sub-shape
Standard_EXPORT void SetCustomTransparency (const TopoDS_Shape& theShape,
Standard_Real theTransparency);
//! Customize line width of specified sub-shape
Standard_EXPORT void SetCustomWidth (const TopoDS_Shape& theShape,
const Standard_Real theLineWidth);

View File

@@ -31,43 +31,34 @@
static Handle(Prs3d_LineAspect) GetLineAspect(const Handle(Prs3d_Drawer)& Dr,
const AIS_TypeOfAttribute Att)
{
switch(Att){
switch(Att)
{
case AIS_TOA_Line:
return Dr->LineAspect();
break;
case AIS_TOA_Dimension:
return Dr->DimensionAspect()->LineAspect();
break;
case AIS_TOA_Wire:
return Dr->WireAspect();
break;
case AIS_TOA_Plane:
return Dr->PlaneAspect()->EdgesAspect();
break;
case AIS_TOA_Vector:
return Dr->VectorAspect();
break;
case AIS_TOA_UIso:
return Handle(Prs3d_LineAspect) (Dr->UIsoAspect());
break;
case AIS_TOA_VIso:
return Handle(Prs3d_LineAspect) (Dr->VIsoAspect());
break;
case AIS_TOA_Free:
return Dr->FreeBoundaryAspect();
break;
case AIS_TOA_UnFree:
return Dr->UnFreeBoundaryAspect();
break;
case AIS_TOA_Section:
return Dr->SectionAspect();
break;
case AIS_TOA_Hidden:
return Dr->HiddenLineAspect();
break;
case AIS_TOA_Seen:
return Dr->SeenLineAspect();
break;
case AIS_TOA_FaceBoundary:
return Dr->FaceBoundaryAspect();
case AIS_TOA_FirstAxis:
return Dr->DatumAspect()->LineAspect(Prs3d_DP_XAxis);
case AIS_TOA_SecondAxis:

View File

@@ -416,7 +416,14 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer th
if (toUpdateViewer
&& theToRedrawOnUpdate)
{
theView->Viewer()->Update();
if (theView->ComputedMode())
{
theView->Viewer()->Update();
}
else
{
theView->Viewer()->RedrawImmediate();
}
}
return aStatus;

View File

@@ -615,31 +615,9 @@ void AIS_InteractiveObject::SynchronizeAspects()
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Presentation()->Groups()); aGroupIter.More(); aGroupIter.Next())
{
Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
if (aGrp.IsNull())
if (!aGroupIter.Value().IsNull())
{
continue;
}
Handle(Graphic3d_AspectLine3d) aLineAspect = aGrp->LineAspect();
Handle(Graphic3d_AspectFillArea3d) aFaceAspect = aGrp->FillAreaAspect();
Handle(Graphic3d_AspectMarker3d) aMarkerAspect = aGrp->MarkerAspect();
Handle(Graphic3d_AspectText3d) aTextAspect = aGrp->TextAspect();
if (!aLineAspect.IsNull())
{
aGrp->SetGroupPrimitivesAspect (aLineAspect);
}
if (!aFaceAspect.IsNull())
{
aGrp->SetGroupPrimitivesAspect (aFaceAspect);
}
if (!aMarkerAspect.IsNull())
{
aGrp->SetGroupPrimitivesAspect (aMarkerAspect);
}
if (!aTextAspect.IsNull())
{
aGrp->SetGroupPrimitivesAspect (aTextAspect);
aGroupIter.ChangeValue()->SynchronizeAspects();
}
}
}

View File

@@ -271,6 +271,18 @@ void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_Ma
}
}
//=======================================================================
//function : SetPart
//purpose :
//=======================================================================
void AIS_Manipulator::SetPart (const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
SetPart (anIt, theMode, theIsEnabled);
}
}
//=======================================================================
//function : EnableMode
//purpose :
@@ -481,6 +493,7 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
const gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
if (!anExtrema.IsDone()
|| anExtrema.IsParallel()
|| anExtrema.NbExt() != 1)
{
// translation cannot be done co-directed with camera
@@ -526,7 +539,9 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
const gp_Pnt aPosLoc = myStartPosition.Location();
const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
if (!aIntersector.IsDone()
|| aIntersector.IsParallel()
|| aIntersector.NbPoints() < 1)
{
return Standard_False;
}
@@ -995,10 +1010,14 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
if (!myAxes[anIt].HasTranslation())
{
continue;
}
const Axis& anAxis = myAxes[anIt];
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Translation, 9);
}
// define sensitivity by line
Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
@@ -1016,6 +1035,10 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
if (!myAxes[anIt].HasRotation())
{
continue;
}
const Axis& anAxis = myAxes[anIt];
if (aMode != AIS_MM_None)
{
@@ -1036,6 +1059,10 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
{
for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
{
if (!myAxes[anIt].HasScaling())
{
continue;
}
if (aMode != AIS_MM_None)
{
anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);

View File

@@ -112,6 +112,12 @@ public:
//! @warning Raises program error if axis index is < 0 or > 2.
Standard_EXPORT void SetPart (const Standard_Integer theAxisIndex, const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled);
//! Disable or enable visual parts for translation, rotation or scaling for ALL axes.
//! By default all parts are enabled (will be displayed).
//! @warning Enabling or disabling of visual parts of manipulator does not manage the manipulation (selection) mode.
//! @warning Raises program error if axis index is < 0 or > 2.
Standard_EXPORT void SetPart (const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled);
//! Behavior settings to be applied when performing transformation:
//! - FollowTranslation - whether the manipulator will be moved together with an object.
//! - FollowRotation - whether the manipulator will be rotated together with an object.

View File

@@ -299,13 +299,13 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
Standard_Integer aPtsLower = myPoints.Lower();
Standard_Integer aPtsUpper = myPoints.Upper();
BRepMesh::Array1OfInteger anIndexes (0, myPoints.Length() - 1);
IMeshData::VectorOfInteger anIndexes (myPoints.Length(), anAllocator);
for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
{
gp_XY aP ((Standard_Real)myPoints.Value (aPtIdx).x(),
(Standard_Real)myPoints.Value (aPtIdx).y());
BRepMesh_Vertex aVertex (aP, aPtIdx, BRepMesh_Frontier);
anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
anIndexes.Append (aMeshStructure->AddNode (aVertex));
}
Standard_Real aPtSum = 0;
@@ -328,7 +328,7 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
}
BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
const IMeshData::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
if (aTriangles.Extent() < 1)
return Standard_False;
@@ -341,7 +341,7 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
}
Standard_Integer aVertexIndex = 1;
BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
IMeshData::IteratorOfMapOfInteger aTriangleIt (aTriangles);
for (; aTriangleIt.More(); aTriangleIt.Next())
{
const Standard_Integer aTriangleId = aTriangleIt.Key();

View File

@@ -346,64 +346,16 @@ Standard_Real AIS_Shape::Transparency() const {
//purpose :
//=======================================================================
void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
bool AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
const Quantity_Color& theColor) const
{
if (!theDrawer->HasOwnShadingAspect())
bool toRecompute = false;
toRecompute = theDrawer->SetupOwnShadingAspect() || toRecompute;
toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
if (theDrawer->SetupOwnPointAspect())
{
theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
if (theDrawer->HasLink())
{
*theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
}
}
if (!theDrawer->HasOwnLineAspect())
{
theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
}
}
if (!theDrawer->HasOwnWireAspect())
{
theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
}
}
if (!theDrawer->HasOwnPointAspect())
{
theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_BLACK, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
}
}
if (!theDrawer->HasOwnFreeBoundaryAspect())
{
theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
}
}
if (!theDrawer->HasOwnUnFreeBoundaryAspect())
{
theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
}
}
if (!theDrawer->HasOwnSeenLineAspect())
{
theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
}
toRecompute = true;
}
// override color
@@ -414,6 +366,8 @@ void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
theDrawer->FreeBoundaryAspect()->SetColor (theColor);
theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
theDrawer->SeenLineAspect()->SetColor (theColor);
theDrawer->FaceBoundaryAspect()->SetColor (theColor);
return toRecompute;
}
//=======================================================================
@@ -423,9 +377,16 @@ void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
void AIS_Shape::SetColor (const Quantity_Color& theColor)
{
setColor (myDrawer, theColor);
const bool toRecompute = setColor (myDrawer, theColor);
myDrawer->SetColor (theColor);
hasOwnColor = Standard_True;
if (!toRecompute)
{
myToRecomputeModes.Clear();
myRecomputeEveryPrs = false;
SynchronizeAspects();
return;
}
// modify shading presentation without re-computation
const PrsMgr_Presentations& aPrsList = Presentations();
@@ -477,8 +438,10 @@ void AIS_Shape::UnsetColor()
if (!HasColor())
{
myToRecomputeModes.Clear();
myRecomputeEveryPrs = false;
return;
}
hasOwnColor = Standard_False;
myDrawer->SetColor (myDrawer->HasLink() ? myDrawer->Link()->Color() : Quantity_Color (Quantity_NOC_WHITE));
@@ -490,6 +453,7 @@ void AIS_Shape::UnsetColor()
myDrawer->SetFreeBoundaryAspect (anEmptyAsp);
myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
myDrawer->SetSeenLineAspect (anEmptyAsp);
myDrawer->SetFaceBoundaryAspect (anEmptyAsp);
}
else
{
@@ -522,6 +486,12 @@ void AIS_Shape::UnsetColor()
AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen, aColor);
}
myDrawer->SeenLineAspect()->SetColor (aColor);
aColor = Quantity_NOC_BLACK;
if (myDrawer->HasLink())
{
AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_FaceBoundary, aColor);
}
myDrawer->FaceBoundaryAspect()->SetColor (aColor);
}
if (!myDrawer->HasOwnShadingAspect())
@@ -568,40 +538,7 @@ void AIS_Shape::UnsetColor()
myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
}
myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
// modify shading presentation without re-computation
const PrsMgr_Presentations& aPrsList = Presentations();
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
Handle(Graphic3d_AspectLine3d) aLineAsp = myDrawer->LineAspect()->Aspect();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() != AIS_Shaded)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
// Check if aspect of given type is set for the group,
// because setting aspect for group with no already set aspect
// can lead to loss of presentation data
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetGroupPrimitivesAspect (anAreaAsp);
}
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
{
aGroup->SetGroupPrimitivesAspect (aLineAsp);
}
}
}
LoadRecomputable (AIS_WireFrame);
LoadRecomputable (2);
myRecomputeEveryPrs = true;
}
//=======================================================================
@@ -609,49 +546,10 @@ void AIS_Shape::UnsetColor()
//purpose :
//=======================================================================
void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
bool AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
const Standard_Real theLineWidth) const
{
if (!theDrawer->HasOwnLineAspect())
{
theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
}
}
if (!theDrawer->HasOwnWireAspect())
{
theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
}
}
if (!theDrawer->HasOwnFreeBoundaryAspect())
{
theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
}
}
if (!theDrawer->HasOwnUnFreeBoundaryAspect())
{
theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
}
}
if (!theDrawer->HasOwnSeenLineAspect())
{
theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
if (theDrawer->HasLink())
{
*theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
}
}
bool toRecompute = theDrawer->SetOwnLineAspects();
// override width
theDrawer->LineAspect()->SetWidth (theLineWidth);
@@ -659,6 +557,8 @@ void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
theDrawer->SeenLineAspect()->SetWidth (theLineWidth);
theDrawer->FaceBoundaryAspect()->SetWidth (theLineWidth);
return toRecompute;
}
//=======================================================================
@@ -668,10 +568,17 @@ void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
void AIS_Shape::SetWidth (const Standard_Real theLineWidth)
{
setWidth (myDrawer, theLineWidth);
myOwnWidth = theLineWidth;
LoadRecomputable (AIS_WireFrame); // means that it is necessary to recompute only the wireframe....
LoadRecomputable (2); // and the bounding box...
if (setWidth (myDrawer, theLineWidth))
{
myRecomputeEveryPrs = true;
}
else
{
myRecomputeEveryPrs = false;
myToRecomputeModes.Clear();
SynchronizeAspects();
}
}
//=======================================================================
@@ -684,20 +591,21 @@ void AIS_Shape::UnsetWidth()
if (myOwnWidth == 0.0)
{
myToRecomputeModes.Clear();
myRecomputeEveryPrs = false;
return;
}
myOwnWidth = 0.0;
Handle(Prs3d_LineAspect) anEmptyAsp;
if (!HasColor())
{
const Handle(Prs3d_LineAspect) anEmptyAsp;
myDrawer->SetLineAspect (anEmptyAsp);
myDrawer->SetWireAspect (anEmptyAsp);
myDrawer->SetFreeBoundaryAspect (anEmptyAsp);
myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
myDrawer->SetSeenLineAspect (anEmptyAsp);
myDrawer->SetFaceBoundaryAspect (anEmptyAsp);
myRecomputeEveryPrs = true;
}
else
{
@@ -711,8 +619,12 @@ void AIS_Shape::UnsetWidth()
AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_UnFree) : 1.);
myDrawer->SeenLineAspect() ->SetWidth (myDrawer->HasLink() ?
AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Seen) : 1.);
myDrawer->FaceBoundaryAspect() ->SetWidth (myDrawer->HasLink() ?
AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_FaceBoundary) : 1.);
SynchronizeAspects();
myToRecomputeModes.Clear();
myRecomputeEveryPrs = false;
}
LoadRecomputable (AIS_WireFrame);
}
//=======================================================================
@@ -727,14 +639,7 @@ void AIS_Shape::setMaterial (const Handle(Prs3d_Drawer)& theDrawer,
{
const Quantity_Color aColor = theDrawer->ShadingAspect()->Material (myCurrentFacingModel).Color();
const Standard_Real aTransp = theDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
if (!theDrawer->HasOwnShadingAspect())
{
theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
if (theDrawer->HasLink())
{
*theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
}
}
theDrawer->SetupOwnShadingAspect();
theDrawer->ShadingAspect()->SetMaterial (theMaterial, myCurrentFacingModel);
if (theToKeepColor)
@@ -858,15 +763,7 @@ void AIS_Shape::UnsetMaterial()
void AIS_Shape::setTransparency (const Handle(Prs3d_Drawer)& theDrawer,
const Standard_Real theValue) const
{
if (!theDrawer->HasOwnShadingAspect())
{
theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
if (theDrawer->HasLink())
{
*theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
}
}
theDrawer->SetupOwnShadingAspect();
// override transparency
theDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
}

View File

@@ -51,7 +51,7 @@
//! To generate texture coordinates, appropriate shading attribute should be set before computing presentation in AIS_Shaded display mode:
//! @code
//! Handle(AIS_Shape) aPrs = new AIS_Shape();
//! aPrs->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
//! aPrs->Attributes()->SetupOwnShadingAspect();
//! aPrs->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn();
//! aPrs->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (new Graphic3d_Texture2Dmanual (Graphic3d_NOT_2D_ALUMINUM));
//! @endcode
@@ -174,8 +174,7 @@ public:
Standard_EXPORT virtual void UnsetColor() Standard_OVERRIDE;
//! Sets the value aValue for line width in the reconstructed compound shape.
//! Changes line aspects for lines-only presentation modes like Wireframe and Bounding Box.
//! Doesn't change face boundary line aspect.
//! Changes line aspects for lines presentation.
Standard_EXPORT virtual void SetWidth (const Standard_Real aValue) Standard_OVERRIDE;
//! Removes the setting for line width in the reconstructed compound shape.
@@ -305,9 +304,13 @@ protected:
Standard_EXPORT void LoadRecomputable (const Standard_Integer TheMode);
Standard_EXPORT void setColor (const Handle(Prs3d_Drawer)& theDrawer, const Quantity_Color& theColor) const;
//! Create own aspects (if they do not exist) and set color to them.
//! @return TRUE if new aspects have been created
Standard_EXPORT bool setColor (const Handle(Prs3d_Drawer)& theDrawer, const Quantity_Color& theColor) const;
Standard_EXPORT void setWidth (const Handle(Prs3d_Drawer)& theDrawer, const Standard_Real theWidth) const;
//! Create own aspects (if they do not exist) and set width to them.
//! @return TRUE if new aspects have been created
Standard_EXPORT bool setWidth (const Handle(Prs3d_Drawer)& theDrawer, const Standard_Real theWidth) const;
Standard_EXPORT void setTransparency (const Handle(Prs3d_Drawer)& theDrawer, const Standard_Real theValue) const;

View File

@@ -335,6 +335,10 @@ void AIS_Trihedron::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManag
}
aGroup->AddPrimitiveArray (arrayOfPrimitives(aPart));
if (aPresentation->GetZLayer() != theStyle->ZLayer())
{
aPresentation->SetZLayer (theStyle->ZLayer());
}
aPresentation->Highlight (theStyle);
thePM->AddToImmediateList (aPresentation);
}

View File

@@ -32,6 +32,7 @@ AIS_TOA_UnFree,
AIS_TOA_Section,
AIS_TOA_Hidden,
AIS_TOA_Seen,
AIS_TOA_FaceBoundary,
AIS_TOA_FirstAxis,
AIS_TOA_SecondAxis,
AIS_TOA_ThirdAxis

View File

@@ -19,6 +19,8 @@ AIS_BadEdgeFilter.cxx
AIS_BadEdgeFilter.hxx
AIS_C0RegularityFilter.cxx
AIS_C0RegularityFilter.hxx
AIS_CameraFrustum.cxx
AIS_CameraFrustum.hxx
AIS_Chamf2dDimension.cxx
AIS_Chamf2dDimension.hxx
AIS_Chamf2dDimension.lxx

View File

@@ -1,6 +1,5 @@
Adaptor2d_Curve2d.cxx
Adaptor2d_Curve2d.hxx
Adaptor2d_Curve2dPtr.hxx
Adaptor2d_GenHCurve2d.gxx
Adaptor2d_GenHCurve2d.lxx
Adaptor2d_HCurve2d.cxx

View File

@@ -303,14 +303,28 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
sprintf(name, "bc2d_%d_%d", indc, nbbc);
DrawTrSurf::Set(name, theBezier2d);
#endif
gp_Vec2d FirstVec, SecondVec;
FirstVec = gp_Vec2d(aPoles2d(1), aPoles2d(2));
FirstVec.Normalize();
const Standard_Real aSqNormToler = Epsilon(1.0)*Epsilon(1.0);
gp_Vec2d FirstVec(aPoles2d(1), aPoles2d(2)), SecondVec;
Standard_Real aVecSqNorm = FirstVec.SquareMagnitude();
if (aVecSqNorm < aSqNormToler)
{
theIndbad = theIndfirst + 1;
return Standard_False;
}
FirstVec /= Sqrt(aSqNormToler);
gp_Pnt2d MidPnt = aPoles2d(2);
for (Standard_Integer k = 3; k <= aPoles2d.Upper(); k++)
{
SecondVec = gp_Vec2d(MidPnt, aPoles2d(k));
SecondVec.Normalize();
SecondVec.SetXY(aPoles2d(k).XY() - MidPnt.XY());
aVecSqNorm = SecondVec.SquareMagnitude();
if (aVecSqNorm < aSqNormToler)
{
theIndbad = theIndfirst + k - 1;
return Standard_False;
}
SecondVec /= Sqrt(aVecSqNorm);
Standard_Real ScalProd = FirstVec * SecondVec;
if (ScalProd < MinScalProd)
{

View File

@@ -26,9 +26,11 @@ IMPLEMENT_STANDARD_RTTIEXT(Aspect_DisplayConnection,Standard_Transient)
Aspect_DisplayConnection::Aspect_DisplayConnection()
{
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
myDisplay = NULL;
myIsOwnDisplay = false;
OSD_Environment anEnv ("DISPLAY");
myDisplayName = anEnv.Value();
Init();
Init (NULL);
#endif
}
@@ -39,7 +41,8 @@ Aspect_DisplayConnection::Aspect_DisplayConnection()
Aspect_DisplayConnection::~Aspect_DisplayConnection()
{
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
if (myDisplay != NULL)
if (myDisplay != NULL
&& myIsOwnDisplay)
{
XCloseDisplay (myDisplay);
}
@@ -52,38 +55,39 @@ Aspect_DisplayConnection::~Aspect_DisplayConnection()
// purpose :
// =======================================================================
Aspect_DisplayConnection::Aspect_DisplayConnection (const TCollection_AsciiString& theDisplayName)
: myDisplay (NULL),
myIsOwnDisplay (false)
{
myDisplayName = theDisplayName;
Init();
Init (NULL);
}
// =======================================================================
// function : GetDisplay
// function : Aspect_DisplayConnection
// purpose :
// =======================================================================
Display* Aspect_DisplayConnection::GetDisplay()
Aspect_DisplayConnection::Aspect_DisplayConnection (Display* theDisplay)
: myDisplay (NULL),
myIsOwnDisplay (false)
{
return myDisplay;
}
// =======================================================================
// function : GetDisplayName
// purpose :
// =======================================================================
TCollection_AsciiString Aspect_DisplayConnection::GetDisplayName()
{
return myDisplayName;
Init (theDisplay);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
void Aspect_DisplayConnection::Init()
void Aspect_DisplayConnection::Init (Display* theDisplay)
{
myDisplay = XOpenDisplay (myDisplayName.ToCString());
myAtoms.Bind (Aspect_XA_DELETE_WINDOW, XInternAtom(myDisplay, "WM_DELETE_WINDOW", False));
if (myDisplay != NULL
&& myIsOwnDisplay)
{
XCloseDisplay (myDisplay);
}
myIsOwnDisplay = false;
myAtoms.Clear();
myDisplay = theDisplay != NULL ? theDisplay : XOpenDisplay (myDisplayName.ToCString());
if (myDisplay == NULL)
{
TCollection_AsciiString aMessage;
@@ -91,6 +95,11 @@ void Aspect_DisplayConnection::Init()
aMessage += myDisplayName + "\"";
throw Aspect_DisplayConnectionDefinitionError(aMessage.ToCString());
}
else
{
myIsOwnDisplay = theDisplay == NULL;
myAtoms.Bind (Aspect_XA_DELETE_WINDOW, XInternAtom(myDisplay, "WM_DELETE_WINDOW", False));
}
}
// =======================================================================

View File

@@ -47,25 +47,37 @@ public:
//! screen_number - Specifies the screen to be used on that server. Optional variable.
Aspect_DisplayConnection (const TCollection_AsciiString& theDisplayName);
//! Constructor wrapping existing Display instance.
//! WARNING! it is a responsibility of application to keep this pointer
//! valid while Aspect_DisplayConnection is alive and to close Display when it is no more needed.
Aspect_DisplayConnection (Display* theDisplay);
//! @return pointer to Display structure that serves as the connection to the X server.
Display* GetDisplay();
Display* GetDisplay() { return myDisplay; }
//! @return TRUE if X Display has been allocated by this class
Standard_Boolean IsOwnDisplay() const { return myIsOwnDisplay; }
//! @return identifier(atom) for custom named property associated with windows that use current connection to X server.
Atom GetAtom (const Aspect_XAtom theAtom) const;
//! @return display name for this connection.
TCollection_AsciiString GetDisplayName();
const TCollection_AsciiString& GetDisplayName() { return myDisplayName; }
private:
//! Open connection with display specified in myDisplayName class field.
void Init();
//! Open connection with display specified in myDisplayName class field
//! or takes theDisplay parameter when it is not NULL.
//! WARNING! When external Display is specified, it is a responsibility of application
//! to keep this pointer valid while Aspect_DisplayConnection is alive
//! and to close Display when it is no more needed.
//! @param theDisplay external pointer to allocated Display, or NULL if new connection should be created
void Init (Display* theDisplay);
private:
Display* myDisplay;
NCollection_DataMap<Aspect_XAtom, Atom> myAtoms;
TCollection_AsciiString myDisplayName;
Standard_Boolean myIsOwnDisplay;
#endif
private:

View File

@@ -16,23 +16,17 @@
#ifndef _Aspect_InteriorStyle_HeaderFile
#define _Aspect_InteriorStyle_HeaderFile
//! Definition of interior types for primitive
//! faces.
//!
//! IS_EMPTY no interior.
//! IS_HOLLOW display the boundaries of the surface.
//! IS_HATCH display hatched with a hatch style.
//! IS_SOLID display the interior entirely filled.
//! IS_HIDDENLINE display in hidden lines removed.
//! IS_POINT display only vertices.
//! Interior types for primitive faces.
enum Aspect_InteriorStyle
{
Aspect_IS_EMPTY,
Aspect_IS_HOLLOW,
Aspect_IS_HATCH,
Aspect_IS_SOLID,
Aspect_IS_HIDDENLINE,
Aspect_IS_POINT
Aspect_IS_EMPTY = -1, //!< no interior
Aspect_IS_SOLID = 0, //!< normally filled surface interior
Aspect_IS_HATCH, //!< hatched surface interior
Aspect_IS_HIDDENLINE, //!< interior is filled with viewer background color
Aspect_IS_POINT, //!< display only vertices of surface (obsolete)
// obsolete aliases
Aspect_IS_HOLLOW = Aspect_IS_EMPTY, //!< transparent surface interior
};
#endif // _Aspect_InteriorStyle_HeaderFile

View File

@@ -6,94 +6,121 @@
N/A
.BOPAlgo_AlertBOPIsNotSet
Error: The type of Boolean Operation is not set
The type of Boolean Operation is not set
.BOPAlgo_AlertBOPNotAllowed
Error: Boolean operation of the given type is not allowed on the given inputs
Boolean operation of the given type is not allowed on the given inputs
.BOPAlgo_AlertSolidBuilderFailed
Error: Building Fused solid has failed
Building Fused solid has failed
.BOPAlgo_AlertTooFewArguments
Error: There are no enough arguments to perform the operation
There are no enough arguments to perform the operation
.BOPAlgo_AlertMultipleArguments
Error: More than one argument is provided
More than one argument is provided
.BOPAlgo_AlertNoFiller
Error: The Pave Filler (the intersection tool) has not been created
The Pave Filler (the intersection tool) has not been created
.BOPAlgo_AlertIntersectionFailed
Error: The intersection of the arguments has failed
The intersection of the arguments has failed
.BOPAlgo_AlertBuilderFailed
Error: Building of the result shape has failed
Building of the result shape has failed
.BOPAlgo_AlertNullFace
Error: The face given to be split is a null shape
The face given to be split is a null shape
.BOPAlgo_AlertNullInputShapes
Error: No or null input shapes
No or null input shapes
.BOPAlgo_AlertPostTreatFF
Error: Cannot connect face intersection curves
Cannot connect face intersection curves
.BOPAlgo_AlertEmptyShape
Warning: Some of the arguments are empty shapes
Some of the arguments are empty shapes
.BOPAlgo_AlertSelfInterferingShape
Warning: Some of the arguments are self-interfering shapes
Some of the arguments are self-interfering shapes
.BOPAlgo_AlertTooSmallEdge
Warning: Some edges are too small and have no valid range
Some edges are too small and have no valid range
.BOPAlgo_AlertNotSplittableEdge
Warning: Some edges are very small and have such a small valid range, that they cannot be split
Some edges are very small and have such a small valid range, that they cannot be split
.BOPAlgo_AlertBadPositioning
Warning: The positioning of the shapes leads to creation of the small edges without valid range
The positioning of the shapes leads to creation of the small edges without valid range
.BOPAlgo_AlertShellSplitterFailed
Warning: Unable to build loops from the given faces
Unable to build loops from the given faces
.BOPAlgo_AlertRemovalOfIBForMDimShapes
Warning: Removal of internal boundaries among the multi-dimensional shapes is not supported yet
Removal of internal boundaries among the multi-dimensional shapes is not supported yet
.BOPAlgo_AlertRemovalOfIBForSolidsFailed
Warning: Removal of internal boundaries among Solids has failed
Removal of internal boundaries among Solids has failed
.BOPAlgo_AlertRemovalOfIBForFacesFailed
Warning: Removal of internal boundaries among Faces has failed
Removal of internal boundaries among Faces has failed
.BOPAlgo_AlertRemovalOfIBForEdgesFailed
Warning: Removal of internal boundaries among Edges has failed
Removal of internal boundaries among Edges has failed
.BOPAlgo_AlertIntersectionOfPairOfShapesFailed
Warning: Intersection of pair of shapes has failed
Intersection of pair of shapes has failed
.BOPAlgo_AlertBuildingPCurveFailed
Warning: Building 2D curve of edge on face has failed
Building 2D curve of edge on face has failed
.BOPAlgo_AlertAcquiredSelfIntersection
Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered
Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered
.BOPAlgo_AlertUnsupportedType
Warning: Unsupported type of input shape
Unsupported type of input shape
.BOPAlgo_AlertUnableToRemoveTheFeature
Warning: Unable to remove the feature
Unable to remove the feature
.BOPAlgo_AlertNoFacesToRemove
Error: No faces have been found for removal
No faces have been found for removal
.BOPAlgo_AlertRemoveFeaturesFailed
Error: The Feature Removal algorithm has failed
The Feature Removal algorithm has failed
.BOPAlgo_AlertSolidBuilderUnusedFaces
Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
.BOPAlgo_AlertFaceBuilderUnusedEdges
Warning: Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation
Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation
.BOPAlgo_AlertUnableToOrientTheShape
Warning: Unable to orient the shape correctly
Unable to orient the shape correctly
.BOPAlgo_AlertUnknownShape
Shape is unknown for operation
.BOPAlgo_AlertNoPeriodicityRequired
No periodicity has been requested for the shape
.BOPAlgo_AlertUnableToTrim
Unable to trim the shape for making it periodic (BOP Common fails)
.BOPAlgo_AlertUnableToMakeIdentical
Unable to make the shape to look identical on opposite sides (Splitter fails)
.BOPAlgo_AlertUnableToRepeat
Unable to repeat the shape (Gluer fails)
.BOPAlgo_AlertMultiDimensionalArguments
Multi-dimensional arguments
.BOPAlgo_AlertUnableToMakePeriodic
Unable to make the shape periodic
.BOPAlgo_AlertUnableToGlue
Unable to glue the shapes
.BOPAlgo_AlertShapeIsNotPeriodic
The shape is not periodic

View File

@@ -30,7 +30,7 @@ DEFINE_SIMPLE_ALERT(BOPAlgo_AlertBuilderFailed)
//! The intersection of the arguments has failed
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertIntersectionFailed)
//! The type of Boolean Operation is not set
//! More than one argument is provided
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertMultipleArguments)
//! The Pave Filler (the intersection tool) has not been created
@@ -111,4 +111,31 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertFaceBuilderUnusedEdges)
//! Unable to orient the shape correctly
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToOrientTheShape)
//! Shape is unknown for operation
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnknownShape)
//! No periodicity has been requested for the shape
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertNoPeriodicityRequired)
//! Unable to trim the shape for making it periodic (BOP Common fails)
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToTrim)
//! Unable to make the shape to look identical on opposite sides (Splitter fails)
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToMakeIdentical)
//! Unable to repeat the shape (Gluer fails)
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToRepeat)
//! Multi-dimensional arguments
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertMultiDimensionalArguments)
//! Unable to make the shape periodic
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToMakePeriodic)
//! Unable to glue the shapes
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToGlue)
//! The shape is not periodic
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShapeIsNotPeriodic)
#endif // _BOPAlgo_Alerts_HeaderFile

View File

@@ -30,6 +30,7 @@
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx>
@@ -772,6 +773,32 @@ void BOPAlgo_BOP::BuildRC()
//=======================================================================
void BOPAlgo_BOP::BuildShape()
{
if (myDims[0] == 3 && myDims[1] == 3)
{
// For the Boolean operation on solids we need to check first
// if we are dealing with closed solids, because for open solids
// we cannot expect the BuilderSolid algorithm to produce good
// splits for them and have to try the alternative approach for
// building the result shape.
// This approach is not used by default as it will loose the
// modification history for solids, because the result solid
// will be built from scratch using the splits of faces.
Standard_Boolean hasNotClosedSolids = CheckArgsForOpenSolid();
if (hasNotClosedSolids)
{
Handle(Message_Report) aReport = new Message_Report();
BuildBOP(myArguments, myTools, myOperation, aReport);
if (aReport->GetAlerts(Message_Fail).IsEmpty())
{
// Success. Merge the report into the main report.
myReport->Merge(aReport);
return;
}
}
}
// Build the result using splits of arguments.
BuildRC();
//
if ((myOperation == BOPAlgo_FUSE) && (myDims[0] == 3)) {
@@ -1169,6 +1196,157 @@ void BOPAlgo_BOP::BuildSolid()
//
myShape = aResult;
}
//=======================================================================
//function : CheckArgsForOpenSolid
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_BOP::CheckArgsForOpenSolid()
{
// Analyze the report to find if BuilderSolid has generated warnings
// for any of the solids and collect these solids to check if they are open.
TopTools_MapOfShape aFailedSolids;
{
const Message_ListOfAlert& aList = myReport->GetAlerts(Message_Warning);
for (Message_ListOfAlert::Iterator aIt(aList); aIt.More(); aIt.Next())
{
const Handle(Standard_Type)& aType = aIt.Value()->DynamicType();
if (aType != STANDARD_TYPE(BOPAlgo_AlertSolidBuilderUnusedFaces))
continue;
Handle(TopoDS_AlertWithShape) aShapeAlert = Handle(TopoDS_AlertWithShape)::DownCast(aIt.Value());
if (!aShapeAlert.IsNull())
{
const TopoDS_Shape& aWarnShape = aShapeAlert->GetShape();
if (!aWarnShape.IsNull())
{
TopExp_Explorer expS(aWarnShape, TopAbs_SOLID);
for (; expS.More(); expS.Next())
aFailedSolids.Add(expS.Current());
}
}
}
}
// Iterate on all solids from the arguments and check if any
// of them are not closed.
// At the same time, collect all internal faces of the input solids
// to check if the splits of open solids did not acquire any new
// internal faces.
const Standard_Integer aNbS = myDS->NbSourceShapes();
for (Standard_Integer i = 0; i < aNbS; ++i)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_SOLID)
continue;
const TopoDS_Shape& aSolid = aSI.Shape();
// Check that not INTERNAL faces create closed loops
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
// Collect all splits of internal faces
TopTools_MapOfShape aMFInternal;
for (TopoDS_Iterator itSh(aSolid); itSh.More(); itSh.Next())
{
const TopoDS_Shape& aSh = itSh.Value();
if (aSh.ShapeType() != TopAbs_SHELL)
continue;
for (TopoDS_Iterator itF(aSh); itF.More(); itF.Next())
{
const TopoDS_Shape& aF = itF.Value();
if (aF.Orientation() == TopAbs_INTERNAL)
{
const TopTools_ListOfShape* pLFIm = myImages.Seek(aF);
if (pLFIm)
{
TopTools_ListOfShape::Iterator itLFIm(*pLFIm);
for (; itLFIm.More(); itLFIm.Next())
aMFInternal.Add(itLFIm.Value());
}
else
aMFInternal.Add(aF);
}
else
TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
}
}
// Analyze the Edge-Face connection map on free edges
Standard_Boolean isClosed = Standard_True;
const Standard_Integer aNbE = aMEF.Extent();
for (Standard_Integer j = 1; j <= aNbE && isClosed; ++j)
{
const TopoDS_Edge& aE = TopoDS::Edge(aMEF.FindKey(j));
if (BRep_Tool::Degenerated(aE))
// Skip degenerated edges
continue;
isClosed = (aMEF(j).Extent() > 1);
if (!isClosed)
{
const TopoDS_Face& aF = TopoDS::Face(aMEF(j).First());
isClosed = BRep_Tool::IsClosed(aE, aF); // Check for seam edges
if (!isClosed)
{
// Check if the edge is not internal in the face
TopExp_Explorer expE(aF, TopAbs_EDGE);
for (; expE.More(); expE.Next())
{
if (expE.Current().IsSame(aE))
{
isClosed = (expE.Current().Orientation() == TopAbs_INTERNAL);
break;
}
}
}
}
}
if (isClosed)
continue;
// Not closed solid is found
if (aFailedSolids.Contains(aSolid))
// Warning has been generated for this solid, return positive result right away.
return Standard_True;
// Check the splits not to acquire new INTERNAL faces
const TopTools_ListOfShape *pLSIm = myImages.Seek(aSolid);
if (!pLSIm)
continue;
TopTools_ListOfShape::Iterator itLSIm(*pLSIm);
for (; itLSIm.More(); itLSIm.Next())
{
const TopoDS_Shape& aSIm = itLSIm.Value();
for (TopoDS_Iterator itSh(aSIm); itSh.More(); itSh.Next())
{
const TopoDS_Shape& aSh = itSh.Value();
if (aSh.ShapeType() != TopAbs_SHELL)
continue;
for (TopoDS_Iterator itF(aSh); itF.More(); itF.Next())
{
const TopoDS_Shape& aF = itF.Value();
if (aF.Orientation() == TopAbs_INTERNAL)
{
if (!aMFInternal.Contains(aF))
// New internal face is found
return Standard_True;
}
}
}
}
}
return Standard_False;
}
//=======================================================================
//function : TypeToExplore
//purpose :

View File

@@ -107,6 +107,12 @@ protected:
//! all shapes in one of the groups are empty shapes.
Standard_EXPORT Standard_Boolean TreatEmptyShape();
//! Checks if the arguments of Boolean Operation on solids
//! contain any open solids, for which the building of the splits
//! has failed. In case of positive check, run different procedure
//! for building the result shape.
Standard_EXPORT virtual Standard_Boolean CheckArgsForOpenSolid();
protected:
BOPAlgo_Operation myOperation;

View File

@@ -9,94 +9,121 @@ static const char BOPAlgo_BOPAlgo_msg[] =
"N/A\n"
"\n"
".BOPAlgo_AlertBOPIsNotSet\n"
"Error: The type of Boolean Operation is not set\n"
"The type of Boolean Operation is not set\n"
"\n"
".BOPAlgo_AlertBOPNotAllowed\n"
"Error: Boolean operation of the given type is not allowed on the given inputs\n"
"Boolean operation of the given type is not allowed on the given inputs\n"
"\n"
".BOPAlgo_AlertSolidBuilderFailed\n"
"Error: Building Fused solid has failed\n"
"Building Fused solid has failed\n"
"\n"
".BOPAlgo_AlertTooFewArguments\n"
"Error: There are no enough arguments to perform the operation\n"
"There are no enough arguments to perform the operation\n"
"\n"
".BOPAlgo_AlertMultipleArguments\n"
"Error: More than one argument is provided\n"
"More than one argument is provided\n"
"\n"
".BOPAlgo_AlertNoFiller\n"
"Error: The Pave Filler (the intersection tool) has not been created\n"
"The Pave Filler (the intersection tool) has not been created\n"
"\n"
".BOPAlgo_AlertIntersectionFailed\n"
"Error: The intersection of the arguments has failed\n"
"The intersection of the arguments has failed\n"
"\n"
".BOPAlgo_AlertBuilderFailed\n"
"Error: Building of the result shape has failed\n"
"Building of the result shape has failed\n"
"\n"
".BOPAlgo_AlertNullFace\n"
"Error: The face given to be split is a null shape\n"
"The face given to be split is a null shape\n"
"\n"
".BOPAlgo_AlertNullInputShapes\n"
"Error: No or null input shapes\n"
"No or null input shapes\n"
"\n"
".BOPAlgo_AlertPostTreatFF\n"
"Error: Cannot connect face intersection curves\n"
"Cannot connect face intersection curves\n"
"\n"
".BOPAlgo_AlertEmptyShape\n"
"Warning: Some of the arguments are empty shapes\n"
"Some of the arguments are empty shapes\n"
"\n"
".BOPAlgo_AlertSelfInterferingShape\n"
"Warning: Some of the arguments are self-interfering shapes\n"
"Some of the arguments are self-interfering shapes\n"
"\n"
".BOPAlgo_AlertTooSmallEdge\n"
"Warning: Some edges are too small and have no valid range\n"
"Some edges are too small and have no valid range\n"
"\n"
".BOPAlgo_AlertNotSplittableEdge\n"
"Warning: Some edges are very small and have such a small valid range, that they cannot be split\n"
"Some edges are very small and have such a small valid range, that they cannot be split\n"
"\n"
".BOPAlgo_AlertBadPositioning\n"
"Warning: The positioning of the shapes leads to creation of the small edges without valid range\n"
"The positioning of the shapes leads to creation of the small edges without valid range\n"
"\n"
".BOPAlgo_AlertShellSplitterFailed\n"
"Warning: Unable to build loops from the given faces\n"
"Unable to build loops from the given faces\n"
"\n"
".BOPAlgo_AlertRemovalOfIBForMDimShapes\n"
"Warning: Removal of internal boundaries among the multi-dimensional shapes is not supported yet\n"
"Removal of internal boundaries among the multi-dimensional shapes is not supported yet\n"
"\n"
".BOPAlgo_AlertRemovalOfIBForSolidsFailed\n"
"Warning: Removal of internal boundaries among Solids has failed\n"
"Removal of internal boundaries among Solids has failed\n"
"\n"
".BOPAlgo_AlertRemovalOfIBForFacesFailed\n"
"Warning: Removal of internal boundaries among Faces has failed\n"
"Removal of internal boundaries among Faces has failed\n"
"\n"
".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n"
"Warning: Removal of internal boundaries among Edges has failed\n"
"Removal of internal boundaries among Edges has failed\n"
"\n"
".BOPAlgo_AlertIntersectionOfPairOfShapesFailed\n"
"Warning: Intersection of pair of shapes has failed\n"
"Intersection of pair of shapes has failed\n"
"\n"
".BOPAlgo_AlertBuildingPCurveFailed\n"
"Warning: Building 2D curve of edge on face has failed\n"
"Building 2D curve of edge on face has failed\n"
"\n"
".BOPAlgo_AlertAcquiredSelfIntersection\n"
"Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n"
"Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n"
"\n"
".BOPAlgo_AlertUnsupportedType\n"
"Warning: Unsupported type of input shape\n"
"Unsupported type of input shape\n"
"\n"
".BOPAlgo_AlertUnableToRemoveTheFeature\n"
"Warning: Unable to remove the feature\n"
"Unable to remove the feature\n"
"\n"
".BOPAlgo_AlertNoFacesToRemove\n"
"Error: No faces have been found for removal\n"
"No faces have been found for removal\n"
"\n"
".BOPAlgo_AlertRemoveFeaturesFailed\n"
"Error: The Feature Removal algorithm has failed\n"
"The Feature Removal algorithm has failed\n"
"\n"
".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
"Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"
"Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"
"\n"
".BOPAlgo_AlertFaceBuilderUnusedEdges\n"
"Warning: Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation\n"
"Some of the edges passed to the Face Builder algorithm have not been classified and not used for faces creation\n"
"\n"
".BOPAlgo_AlertUnableToOrientTheShape\n"
"Warning: Unable to orient the shape correctly\n";
"Unable to orient the shape correctly\n"
"\n"
".BOPAlgo_AlertUnknownShape\n"
"Shape is unknown for operation\n"
"\n"
".BOPAlgo_AlertNoPeriodicityRequired\n"
"No periodicity has been requested for the shape\n"
"\n"
".BOPAlgo_AlertUnableToTrim\n"
"Unable to trim the shape for making it periodic (BOP Common fails)\n"
"\n"
".BOPAlgo_AlertUnableToMakeIdentical\n"
"Unable to make the shape to look identical on opposite sides (Splitter fails)\n"
"\n"
".BOPAlgo_AlertUnableToRepeat\n"
"Unable to repeat the shape (Gluer fails)\n"
"\n"
".BOPAlgo_AlertMultiDimensionalArguments\n"
"Multi-dimensional arguments\n"
"\n"
".BOPAlgo_AlertUnableToMakePeriodic\n"
"Unable to make the shape periodic\n"
"\n"
".BOPAlgo_AlertUnableToGlue\n"
"Unable to glue the shapes\n"
"\n"
".BOPAlgo_AlertShapeIsNotPeriodic\n"
"The shape is not periodic\n";

View File

@@ -17,22 +17,24 @@
#include <BOPAlgo_Builder.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <BOPAlgo_BuilderSolid.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Tools.hxx>
#include <BOPDS_DS.hxx>
#include <BOPDS_ShapeInfo.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BRep_Builder.hxx>
#include <IntTools_Context.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
#include <BOPDS_ShapeInfo.hxx>
#include <BOPDS_DS.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <TopoDS_Solid.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfOrientedShape.hxx>
//=======================================================================
@@ -50,6 +52,7 @@ BOPAlgo_Builder::BOPAlgo_Builder()
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
myOrigins(100, myAllocator),
myInParts(100, myAllocator),
myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
@@ -71,6 +74,7 @@ BOPAlgo_Builder::BOPAlgo_Builder
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
myOrigins(100, myAllocator),
myInParts(100, myAllocator),
myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
@@ -101,6 +105,7 @@ void BOPAlgo_Builder::Clear()
myImages.Clear();
myShapesSD.Clear();
myOrigins.Clear();
myInParts.Clear();
}
//=======================================================================
//function : AddArgument
@@ -376,3 +381,366 @@ void BOPAlgo_Builder::PostTreat()
BOPTools_AlgoTools::CorrectTolerances(myShape, aMA, 0.05, myRunParallel);
BOPTools_AlgoTools::CorrectShapeTolerances(myShape, aMA, myRunParallel);
}
//=======================================================================
//function : BuildBOP
//purpose :
//=======================================================================
void BOPAlgo_Builder::BuildBOP(const TopTools_ListOfShape& theObjects,
const TopAbs_State theObjState,
const TopTools_ListOfShape& theTools,
const TopAbs_State theToolsState,
Handle(Message_Report) theReport)
{
if (HasErrors())
return;
// Report for the method
Handle(Message_Report) aReport = theReport.IsNull() ? myReport : theReport;
if (myArguments.IsEmpty() || myShape.IsNull())
{
aReport->AddAlert(Message_Fail, new BOPAlgo_AlertBuilderFailed());
return;
}
// Check the input data
if ((theObjState != TopAbs_IN && theObjState != TopAbs_OUT) ||
(theToolsState != TopAbs_IN && theToolsState != TopAbs_OUT))
{
aReport->AddAlert(Message_Fail, new BOPAlgo_AlertBOPNotSet());
return;
}
// Check input shapes
Standard_Boolean hasObjects = !theObjects.IsEmpty();
Standard_Boolean hasTools = !theTools .IsEmpty();
if (!hasObjects && !hasTools)
{
aReport->AddAlert(Message_Fail, new BOPAlgo_AlertTooFewArguments());
return;
}
// Check that all input solids are from the arguments
for (Standard_Integer i = 0; i < 2; ++i)
{
const TopTools_ListOfShape& aList = !i ? theObjects : theTools;
TopTools_ListOfShape::Iterator itLS(aList);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aS = itLS.Value();
// Check if the shape belongs to the arguments of operation
if (myDS->Index(aS) < 0)
{
aReport->AddAlert(Message_Fail, new BOPAlgo_AlertUnknownShape(aS));
return;
}
// Check if the shape is a solid or collection of them
if (aS.ShapeType() != TopAbs_SOLID)
{
TopTools_ListOfShape aLS;
TopTools_MapOfShape aMFence;
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLS);
TopTools_ListOfShape::Iterator it(aLS);
for (; it.More(); it.Next())
{
const TopoDS_Shape& aSx = it.Value();
if (aSx.ShapeType() != TopAbs_SOLID &&
aSx.ShapeType() != TopAbs_COMPSOLID)
{
aReport->AddAlert(Message_Fail, new BOPAlgo_AlertUnsupportedType(aS));
return;
}
}
}
}
}
// Classification of the faces relatively solids has been made
// on the stage of Solids splitting. All results are saved into
// myInParts map, which connects the solids with its IN faces from
// other arguments. All faces not contained in the list of IN faces
// will be considered as OUT.
// Prepare the maps of splits of solids faces with orientations
TopTools_IndexedMapOfOrientedShape aMObjFacesOri, aMToolFacesOri;
// Prepare the maps of splits of solids faces
TopTools_IndexedMapOfShape aMObjFaces, aMToolFaces;
// Copy the list of IN faces of the solids into map
TopTools_MapOfShape anINObjects, anINTools;
for (Standard_Integer i = 0; i < 2; ++i)
{
const TopTools_ListOfShape& aList = !i ? theObjects : theTools;
TopTools_IndexedMapOfOrientedShape& aMapOri = !i ? aMObjFacesOri : aMToolFacesOri;
TopTools_IndexedMapOfShape& aMap = !i ? aMObjFaces : aMToolFaces;
TopTools_ListOfShape::Iterator itLS(aList);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aShape = itLS.Value();
TopExp_Explorer expS(aShape, TopAbs_SOLID);
for (; expS.More(); expS.Next())
{
const TopoDS_Shape& aS = expS.Current();
TopExp_Explorer expF(aS, TopAbs_FACE);
for (; expF.More(); expF.Next())
{
const TopoDS_Shape& aF = expF.Current();
if (aF.Orientation() != TopAbs_FORWARD &&
aF.Orientation() != TopAbs_REVERSED)
continue;
const TopTools_ListOfShape* pLFIm = myImages.Seek(aF);
if (pLFIm)
{
TopTools_ListOfShape::Iterator itLFIm(*pLFIm);
for (; itLFIm.More(); itLFIm.Next())
{
TopoDS_Face aFIm = TopoDS::Face(itLFIm.Value());
if (BOPTools_AlgoTools::IsSplitToReverse(aFIm, aF, myContext))
aFIm.Reverse();
aMapOri.Add(aFIm);
aMap.Add(aFIm);
}
}
else
{
aMapOri.Add(aF);
aMap.Add(aF);
}
}
// Copy the list of IN faces into a map
const TopTools_ListOfShape* pLFIN = myInParts.Seek(aS);
if (pLFIN)
{
TopTools_MapOfShape& anINMap = !i ? anINObjects : anINTools;
TopTools_ListOfShape::Iterator itLFIn(*pLFIN);
for (; itLFIn.More(); itLFIn.Next())
anINMap.Add(itLFIn.Value());
}
}
}
}
// Now we need to select all faces which will participate in
// building of the resulting solids. The final set of faces
// depends on the given states for the groups.
Standard_Boolean isObjectsIN = (theObjState == TopAbs_IN),
isToolsIN = (theToolsState == TopAbs_IN);
// Shortcuts
Standard_Boolean bAvoidIN = (!isObjectsIN && !isToolsIN), // avoid all in faces
bAvoidINforBoth = (isObjectsIN != isToolsIN); // avoid faces IN for both groups
// Choose which SD faces are needed to be taken - equally or differently oriented faces
Standard_Boolean isSameOriNeeded = (theObjState == theToolsState);
// Resulting faces
TopTools_IndexedMapOfOrientedShape aMResFacesOri;
TopTools_MapOfShape aMResFacesFence;
// Fence map
TopTools_MapOfShape aMFence, aMFToAvoid;
// Oriented fence map
TopTools_MapOfOrientedShape aMFenceOri;
for (Standard_Integer i = 0; i < 2; ++i)
{
const TopTools_IndexedMapOfOrientedShape& aMap = !i ? aMObjFacesOri : aMToolFacesOri;
const TopTools_IndexedMapOfShape& anOppositeMap = !i ? aMToolFaces : aMObjFaces;
const TopTools_MapOfShape& anINMap = !i ? anINObjects : anINTools;
const TopTools_MapOfShape& anOppositeINMap = !i ? anINTools : anINObjects;
const Standard_Boolean bTakeIN = !i ? isObjectsIN : isToolsIN;
const Standard_Integer aNbF = aMap.Extent();
for (Standard_Integer j = 1; j <= aNbF; ++j)
{
TopoDS_Shape aFIm = aMap(j);
Standard_Boolean isIN = anINMap.Contains(aFIm);
Standard_Boolean isINOpposite = anOppositeINMap.Contains(aFIm);
// Filtering for FUSE - avoid any IN faces
if (bAvoidIN && (isIN || isINOpposite))
continue;
// Filtering for CUT - avoid faces IN for both groups
if (bAvoidINforBoth && isIN && isINOpposite)
continue;
// Treatment of SD faces
if (!aMFence.Add(aFIm))
{
if (!anOppositeMap.Contains(aFIm))
{
// The face belongs to only one group
if (bTakeIN != isSameOriNeeded)
aMFToAvoid.Add(aFIm);
}
else
{
// The face belongs to both groups.
// Using its orientation decide if it is needed in the result or not.
Standard_Boolean isSameOri = !aMFenceOri.Add(aFIm);
if (isSameOriNeeded == isSameOri)
{
// Take the shape without classification
if (aMResFacesFence.Add(aFIm))
aMResFacesOri.Add(aFIm);
}
else
// Remove the face
aMFToAvoid.Add(aFIm);
continue;
}
}
if (!aMFenceOri.Add(aFIm))
continue;
if (bTakeIN == isINOpposite)
{
if (isIN)
{
aMResFacesOri.Add(aFIm);
aMResFacesOri.Add(aFIm.Reversed());
}
else if (bTakeIN && !isSameOriNeeded)
aMResFacesOri.Add(aFIm.Reversed());
else
aMResFacesOri.Add(aFIm);
aMResFacesFence.Add(aFIm);
}
}
}
// Remove the faces which has to be avoided
TopTools_ListOfShape aResFaces;
const Standard_Integer aNbRF = aMResFacesOri.Extent();
for (Standard_Integer i = 1; i <= aNbRF; ++i)
{
const TopoDS_Shape& aRF = aMResFacesOri(i);
if (!aMFToAvoid.Contains(aRF))
aResFaces.Append(aRF);
}
BRep_Builder aBB;
// Try to build closed solids from the faces
BOPAlgo_BuilderSolid aBS;
aBS.SetShapes(aResFaces);
aBS.SetRunParallel(myRunParallel);
aBS.SetContext(myContext);
aBS.SetFuzzyValue(myFuzzyValue);
aBS.SetProgressIndicator(myProgressIndicator);
aBS.Perform();
// Resulting solids
TopTools_ListOfShape aResSolids;
aMFence.Clear();
if (!aBS.HasErrors())
{
// If any, add solids into resulting compound
TopTools_ListIteratorOfListOfShape itA(aBS.Areas());
for (; itA.More(); itA.Next())
{
const TopoDS_Shape& aSolid = itA.Value();
// The solid must contain at least one face
// from either of objects or tools
TopExp_Explorer expF(aSolid, TopAbs_FACE);
for (; expF.More(); expF.Next())
{
const TopoDS_Shape& aF = expF.Current();
if (aMObjFacesOri.Contains(aF) || aMToolFacesOri.Contains(aF))
break;
}
if (expF.More())
{
aResSolids.Append(aSolid);
TopExp::MapShapes(aSolid, aMFence);
}
}
}
// Collect unused faces
TopoDS_Compound anUnUsedFaces;
aBB.MakeCompound(anUnUsedFaces);
TopTools_ListOfShape::Iterator itLF(aResFaces);
for (; itLF.More(); itLF.Next())
{
if (aMFence.Add(itLF.Value()))
aBB.Add(anUnUsedFaces, itLF.Value());
}
// Build blocks from the unused faces
TopTools_ListOfShape aLCB;
BOPTools_AlgoTools::MakeConnexityBlocks(anUnUsedFaces, TopAbs_EDGE, TopAbs_FACE, aLCB);
// Build solid from each block
TopTools_ListIteratorOfListOfShape itCB(aLCB);
for (; itCB.More(); itCB.Next())
{
const TopoDS_Shape& aCB = itCB.Value();
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
// Add faces of the block to the shell
TopExp_Explorer anExpF(aCB, TopAbs_FACE);
for (; anExpF.More(); anExpF.Next())
aBB.Add(aShell, TopoDS::Face(anExpF.Current()));
BOPTools_AlgoTools::OrientFacesOnShell(aShell);
// Make solid out of the shell
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
aBB.Add(aSolid, aShell);
// Add new solid to result
aResSolids.Append(aSolid);
}
if (!bAvoidIN)
{
// Fill solids with internal parts coming with the solids
TopTools_ListOfShape anInParts;
for (Standard_Integer i = 0; i < 2; ++i)
{
const TopTools_ListOfShape& aList = !i ? theObjects : theTools;
TopTools_ListOfShape::Iterator itLS(aList);
for (; itLS.More(); itLS.Next())
{
TopExp_Explorer expS(itLS.Value(), TopAbs_SOLID);
for (; expS.More(); expS.Next())
{
const TopoDS_Shape& aS = expS.Current(); // Solid
for (TopoDS_Iterator it(aS); it.More(); it.Next())
{
const TopoDS_Shape& aSInt = it.Value();
if (aSInt.Orientation() == TopAbs_INTERNAL)
anInParts.Append(aSInt); // vertex or edge
else
{
// shell treatment
TopoDS_Iterator itInt(aSInt);
if (itInt.More() && itInt.Value().Orientation() == TopAbs_INTERNAL)
anInParts.Append(aSInt);
}
}
}
}
}
BOPAlgo_Tools::FillInternals(aResSolids, anInParts, myImages, myContext);
}
// Combine solids into compound
TopoDS_Shape aResult;
aBB.MakeCompound(TopoDS::Compound(aResult));
TopTools_ListOfShape::Iterator itLS(aResSolids);
for (; itLS.More(); itLS.Next())
aBB.Add(aResult, itLS.Value());
myShape = aResult;
PrepareHistory();
}

View File

@@ -25,6 +25,7 @@
#include <BOPAlgo_PPaveFiller.hxx>
#include <BOPAlgo_BuilderShape.hxx>
#include <BOPAlgo_GlueEnum.hxx>
#include <BOPAlgo_Operation.hxx>
#include <BOPDS_PDS.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <Standard_Integer.hxx>
@@ -38,6 +39,7 @@
class IntTools_Context;
class TopoDS_Shape;
class BOPAlgo_PaveFiller;
class TopoDS_Solid;
//!
//! The class is a General Fuse algorithm - base algorithm for the
@@ -174,6 +176,114 @@ public: //! @name Performing the operation
Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
public: //! @name BOPs on open solids
//! Builds the result shape according to the given states for the objects
//! and tools. These states can be unambiguously converted into the Boolean operation type.
//! Thus, it performs the Boolean operation on the given groups of shapes.
//!
//! The result is built basing on the result of Builder operation (GF or any other).
//! The only condition for the Builder is that the splits of faces should be created
//! and classified relatively solids.
//!
//! The method uses classification approach for choosing the faces which will
//! participate in building the result shape:
//! - All faces from each group having the given state for the opposite group
//! will be taken into result.
//!
//! Such approach shows better results (in comparison with BOPAlgo_BuilderSolid approach)
//! when working with open solids. However, the result may not be always
//! correct on such data (at least, not as expected) as the correct classification
//! of the faces relatively open solids is not always possible and may vary
//! depending on the chosen classification point on the face.
//!
//! History is not created for the solids in this method.
//!
//! To avoid pollution of the report of Builder algorithm, there is a possibility to pass
//! the different report to collect the alerts of the method only. But, if the new report
//! is not given, the Builder report will be used.
//! So, even if Builder passed without any errors, but some error has been stored into its report
//! in this method, for the following calls the Builder report must be cleared.
//!
//! The method may set the following errors:
//! - BOPAlgo_AlertBuilderFailed - Building operation has not been performed yet or failed;
//! - BOPAlgo_AlertBOPNotSet - invalid BOP type is given (COMMON/FUSE/CUT/CUT21 are supported);
//! - BOPAlgo_AlertTooFewArguments - arguments are not given;
//! - BOPAlgo_AlertUnknownShape - the shape is unknown for the operation.
//!
//! Parameters:
//! @param theObjects - The group of Objects for BOP;
//! @param theObjState - State for objects faces to pass into result;
//! @param theTools - The group of Tools for BOP;
//! @param theObjState - State for tools faces to pass into result;
//! @param theReport - The alternative report to avoid pollution of the main one.
Standard_EXPORT virtual void BuildBOP(const TopTools_ListOfShape& theObjects,
const TopAbs_State theObjState,
const TopTools_ListOfShape& theTools,
const TopAbs_State theToolsState,
Handle(Message_Report) theReport = NULL);
//! Builds the result of Boolean operation of given type
//! basing on the result of Builder operation (GF or any other).
//!
//! The method converts the given type of operation into the states
//! for the objects and tools required for their face to pass into result
//! and performs the call to the same method, but with states instead
//! of operation type.
//!
//! The conversion looks as follows:
//! - COMMON is built from the faces of objects located IN any of the tools
//! and vice versa.
//! - FUSE is built from the faces OUT of all given shapes;
//! - CUT is built from the faces of the objects OUT of the tools and
//! faces of the tools located IN solids of the objects.
//!
//! @param theObjects - The group of Objects for BOP;
//! @param theTools - The group of Tools for BOP;
//! @param theOperation - The BOP type;
//! @param theReport - The alternative report to avoid pollution of the global one.
void BuildBOP(const TopTools_ListOfShape& theObjects,
const TopTools_ListOfShape& theTools,
const BOPAlgo_Operation theOperation,
Handle(Message_Report) theReport = NULL)
{
TopAbs_State anObjState, aToolsState;
switch (theOperation)
{
case BOPAlgo_COMMON:
{
anObjState = TopAbs_IN;
aToolsState = TopAbs_IN;
break;
}
case BOPAlgo_FUSE:
{
anObjState = TopAbs_OUT;
aToolsState = TopAbs_OUT;
break;
}
case BOPAlgo_CUT:
{
anObjState = TopAbs_OUT;
aToolsState = TopAbs_IN;
break;
}
case BOPAlgo_CUT21:
{
anObjState = TopAbs_IN;
aToolsState = TopAbs_OUT;
break;
}
default:
{
anObjState = TopAbs_UNKNOWN;
aToolsState = TopAbs_UNKNOWN;
break;
}
}
BuildBOP(theObjects, anObjState, theTools, aToolsState, theReport);
}
protected: //! @name History methods
//! Prepare information for history support.
@@ -315,15 +425,11 @@ protected: //! @name Fill Images of SOLIDS
TopTools_ListOfShape& theLIF);
//! Finds faces located inside each solid.
Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts,
TopTools_DataMapOfShapeShape& theDraftSolids,
const Handle(NCollection_BaseAllocator)& theAllocator);
Standard_EXPORT virtual void FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids);
//! Builds the splits of the solids using their draft versions
//! and faces located inside.
Standard_EXPORT void BuildSplitSolids (TopTools_DataMapOfShapeListOfShape& theInParts,
TopTools_DataMapOfShapeShape& theDraftSolids,
const Handle(NCollection_BaseAllocator)& theAllocator);
Standard_EXPORT void BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids);
//! Classifies the vertices and edges from the arguments relatively
//! splits of solids and makes them INTERNAL for solids.
@@ -358,6 +464,7 @@ protected: //! @name Fields
TopTools_DataMapOfShapeListOfShape myImages; //!< Images - map of Images of the sub-shapes of arguments
TopTools_DataMapOfShapeShape myShapesSD; //!< ShapesSD - map of SD Shapes
TopTools_DataMapOfShapeListOfShape myOrigins; //!< Origins - map of Origins, back map of Images
TopTools_DataMapOfShapeListOfShape myInParts; //!< InParts - map of own and acquired IN faces of the arguments solids
Standard_Boolean myNonDestructive; //!< Safe processing option allows avoiding modification of the input shapes
BOPAlgo_GlueEnum myGlue; //!< Gluing option allows speeding up the intersection of the input shapes
Standard_Boolean myCheckInverted; //!< Check inverted option allows disabling the check of input solids on inverted status

View File

@@ -112,32 +112,35 @@ void BOPAlgo_Builder::FillImagesVertices()
//function : BuildResult
//purpose :
//=======================================================================
void BOPAlgo_Builder::BuildResult(const TopAbs_ShapeEnum theType)
void BOPAlgo_Builder::BuildResult(const TopAbs_ShapeEnum theType)
{
TopAbs_ShapeEnum aType;
BRep_Builder aBB;
TopTools_MapOfShape aM;
TopTools_ListIteratorOfListOfShape aIt, aItIm;
//
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
aType=aS.ShapeType();
if (aType==theType) {
if (myImages.IsBound(aS)){
const TopTools_ListOfShape& aLSIm=myImages.Find(aS);
aItIm.Initialize(aLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSIm=aItIm.Value();
if (aM.Add(aSIm)) {
aBB.Add(myShape, aSIm);
}
}
}
else {
if (aM.Add(aS)) {
aBB.Add(myShape, aS);
}
// Fence map
TopTools_MapOfShape aMFence;
// Iterate on all arguments of given type
// and add their images into result
TopTools_ListIteratorOfListOfShape aItA(myArguments);
for (; aItA.More(); aItA.Next())
{
const TopoDS_Shape& aS = aItA.Value();
if (aS.ShapeType() != theType)
continue;
// Get images
const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
if (!pLSIm)
{
// No images -> add the argument shape itself into result
if (aMFence.Add(aS))
BRep_Builder().Add(myShape, aS);
}
else
{
// Add images of the argument shape into result
TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
for (; aItIm.More(); aItIm.Next())
{
const TopoDS_Shape& aSIm = aItIm.Value();
if (aMFence.Add(aSIm))
BRep_Builder().Add(myShape, aSIm);
}
}
}

View File

@@ -292,31 +292,52 @@ void BOPAlgo_Builder::BuildSplitFaces()
if (!aNbPBIn && !aNbPBSc)
{
// If there are any alone vertices to be put in the face,
// the new face has to be created even if the wires of the
// face have not been modified.
// It is also necessary to check if the face contains any internal edges,
// as such edges may split the face on parts and it is better
// to send the face be treated by the BuilderFace algorithm.
// In case of alone vertices the check for internals will be performed
// in the BuildDraftFace method.
Standard_Boolean hasInternals = Standard_False;
if (!aNbAV)
{
// Check if any wires of the face have been modified.
// If not, there is no need to create the new face.
// If no modified and internal wires present in the face
// there is no need to create the new face.
Standard_Boolean hasModified = Standard_False;
TopoDS_Iterator aItW(aF);
for (; aItW.More(); aItW.Next())
{
if (myImages.IsBound(aItW.Value()))
TopoDS_Iterator itE(aItW.Value());
hasInternals = (itE.More() && (itE.Value().Orientation() == TopAbs_INTERNAL));
if (hasInternals)
break;
hasModified |= myImages.IsBound(aItW.Value());
}
if (!aItW.More())
if (!hasInternals && !hasModified)
continue;
}
// No internal parts for the face, so just build the draft face
// and keep it to pass directly into result.
// If the original face has any internal edges or multi-connected vertices,
// the draft face will be null, as such sub-shapes may split the face on parts
// (as in the case "bugs modalg_5 bug25245_1").
// The BuilderFace algorithm will be called in this case.
TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext, myReport);
if (!aFD.IsNull())
if (!hasInternals)
{
aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD);
continue;
// No internal parts for the face, so just build the draft face
// and keep it to pass directly into result.
// If the original face has any internal edges or multi-connected vertices,
// the draft face will be null, as such sub-shapes may split the face on parts
// (as in the case "bugs modalg_5 bug25245_1").
// The BuilderFace algorithm will be called in this case.
TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext, myReport);
if (!aFD.IsNull())
{
aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD);
continue;
}
}
}

View File

@@ -23,6 +23,7 @@
#include <TopAbs_State.hxx>
//
#include <TopoDS.hxx>
#include <TopoDS_AlertWithShape.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Shape.hxx>
@@ -90,29 +91,21 @@ void BOPAlgo_Builder::FillImagesSolids()
if (!bHasSolids) {
return;
}
//
Handle(NCollection_BaseAllocator) aAlr;
//
aAlr=NCollection_BaseAllocator::CommonBaseAllocator();
//
TopTools_DataMapOfShapeListOfShape theInParts(100, aAlr);
TopTools_DataMapOfShapeShape theDraftSolids(100, aAlr);
//
FillIn3DParts(theInParts, theDraftSolids, aAlr);
BuildSplitSolids(theInParts, theDraftSolids, aAlr);
// Draft solids
TopTools_DataMapOfShapeShape aDraftSolids;
// Find all IN faces for all IN faces
FillIn3DParts(aDraftSolids);
// Build split of the solids
BuildSplitSolids(aDraftSolids);
// Fill solids with internal parts
FillInternalShapes();
//
theInParts.Clear();
theDraftSolids.Clear();
}
//=======================================================================
//function : FillIn3DParts
//purpose :
//=======================================================================
void BOPAlgo_Builder::FillIn3DParts
(TopTools_DataMapOfShapeListOfShape& theInParts,
TopTools_DataMapOfShapeShape& theDraftSolids,
const Handle(NCollection_BaseAllocator)& )
void BOPAlgo_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids)
{
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
@@ -224,7 +217,7 @@ void BOPAlgo_Builder::FillIn3DParts
if (aNbInt || aNbIN)
{
// Combine the lists
TopTools_ListOfShape *pLIN = theInParts.Bound(aSolid, TopTools_ListOfShape());
TopTools_ListOfShape *pLIN = myInParts.Bound(aSolid, TopTools_ListOfShape());
TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
for (; aItLS.More(); aItLS.Next())
@@ -360,10 +353,7 @@ typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor,
//function : BuildSplitSolids
//purpose :
//=======================================================================
void BOPAlgo_Builder::BuildSplitSolids
(TopTools_DataMapOfShapeListOfShape& theInParts,
TopTools_DataMapOfShapeShape& theDraftSolids,
const Handle(NCollection_BaseAllocator)& )
void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids)
{
Standard_Boolean bFlagSD;
Standard_Integer i, aNbS;
@@ -417,7 +407,7 @@ void BOPAlgo_Builder::BuildSplitSolids
continue;
const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
const TopTools_ListOfShape* pLFIN = theInParts.Seek(aS);
const TopTools_ListOfShape* pLFIN = myInParts.Seek(aS);
if (!pLFIN || pLFIN->IsEmpty())
{
aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD);
@@ -464,7 +454,35 @@ void BOPAlgo_Builder::BuildSplitSolids
{
BOPAlgo_SplitSolid& aBS = aVBS(k);
aSolidsIm.Add(aBS.Solid(), aBS.Areas());
myReport->Merge(aBS.GetReport());
// Merge BuilderSolid's report into main report,
// assigning the solid with the warnings/errors which
// have been generated for it.
// Convert all errors of BuilderSolid into warnings for main report.
const Handle(Message_Report)& aBSReport = aBS.GetReport();
Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
for (Standard_Integer iGravity = 0; iGravity < 2; iGravity++)
{
const Message_ListOfAlert& anLAlerts = aBSReport->GetAlerts(anAlertTypes[iGravity]);
for (Message_ListOfAlert::Iterator itA(anLAlerts); itA.More(); itA.Next())
{
Handle(Message_Alert) anAlert = itA.Value();
Handle(TopoDS_AlertWithShape) anAlertWithShape = Handle(TopoDS_AlertWithShape)::DownCast(itA.Value());
if (!anAlertWithShape.IsNull())
{
TopoDS_Shape aWarnShape;
BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
BRep_Builder().Add(aWarnShape, aBS.Solid());
BRep_Builder().Add(aWarnShape, anAlertWithShape->GetShape());
anAlertWithShape->SetShape(aWarnShape);
AddWarning(anAlertWithShape);
}
else
AddWarning(anAlert);
}
}
}
//
// Add new solids to images map

View File

@@ -0,0 +1,333 @@
// Created on: 2018-03-29
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPAlgo_MakeConnected.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <BOPAlgo_Builder.hxx>
#include <BOPAlgo_Tools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BRep_Builder.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
//=======================================================================
//function : Perform
//purpose : Makes the shapes connected
//=======================================================================
void BOPAlgo_MakeConnected::Perform()
{
// Check the input data
CheckData();
if (HasErrors())
return;
if (myHistory.IsNull())
myHistory = new BRepTools_History;
// Glue the arguments
MakeConnected();
if (HasErrors())
return;
// Perform material associations for the faces
AssociateMaterials();
if (HasErrors())
return;
}
//=======================================================================
//function : CheckData
//purpose : Check the validity of input data
//=======================================================================
void BOPAlgo_MakeConnected::CheckData()
{
// Check the number of arguments
if (myArguments.IsEmpty())
{
// Not enough arguments
AddError(new BOPAlgo_AlertTooFewArguments());
return;
}
// Check that all shapes in arguments are of the same type
// Extract the shapes from the compound arguments
TopTools_ListOfShape aLA;
// Fence map
TopTools_MapOfShape aMFence;
TopTools_ListIteratorOfListOfShape itLA(myArguments);
for (; itLA.More(); itLA.Next())
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLA);
if (aLA.IsEmpty())
{
// It seems that all argument shapes are empty compounds
AddError(new BOPAlgo_AlertTooFewArguments());
return;
}
// Check dimensions of the extracted non-compound shapes
itLA.Initialize(aLA);
Standard_Integer iDim = BOPTools_AlgoTools::Dimension(itLA.Value());
for (itLA.Next(); itLA.More(); itLA.Next())
{
if (iDim != BOPTools_AlgoTools::Dimension(itLA.Value()))
{
// The arguments are of different type
AddError(new BOPAlgo_AlertMultiDimensionalArguments());
return;
}
}
}
//=======================================================================
//function : MakeConnected
//purpose : Glues the argument shapes
//=======================================================================
void BOPAlgo_MakeConnected::MakeConnected()
{
// Initialize the history
if (myGlueHistory.IsNull())
myGlueHistory = new BRepTools_History;
if (myArguments.Extent() == 1)
{
// No need to glue the single shape
myShape = myArguments.First();
}
else
{
// Glue the shapes
BOPAlgo_Builder aGluer;
aGluer.SetArguments(myArguments);
aGluer.SetGlue(BOPAlgo_GlueShift);
aGluer.SetRunParallel(myRunParallel);
aGluer.SetNonDestructive(Standard_True);
aGluer.Perform();
if (aGluer.HasErrors())
{
// Unable to glue the shapes
TopoDS_Compound aCW;
BRep_Builder().MakeCompound(aCW);
for (TopTools_ListIteratorOfListOfShape it(myArguments); it.More(); it.Next())
BRep_Builder().Add(aCW, it.Value());
AddError(new BOPAlgo_AlertUnableToGlue(aCW));
return;
}
myShape = aGluer.Shape();
// Save the gluing history
myGlueHistory->Merge(aGluer.Arguments(), aGluer);
myHistory->Merge(myGlueHistory);
}
// Keep the glued shape
myGlued = myShape;
// Fill the map of origins
FillOrigins();
}
//=======================================================================
//function : FillOrigins
//purpose : Fills the map of origins
//=======================================================================
void BOPAlgo_MakeConnected::FillOrigins()
{
myOrigins.Clear();
// Map the history shapes of the arguments
if (myAllInputsMap.IsEmpty())
{
TopTools_ListIteratorOfListOfShape itLA(myArguments);
for (; itLA.More(); itLA.Next())
TopExp::MapShapes(itLA.Value(), myAllInputsMap);
}
const Standard_Integer aNbS = myAllInputsMap.Extent();
for (Standard_Integer i = 1; i <= aNbS; ++i)
{
const TopoDS_Shape& aS = myAllInputsMap(i);
if (!BRepTools_History::IsSupportedType(aS))
continue;
// Get Modified & Generated shapes
for (Standard_Integer j = 0; j < 2; ++j)
{
const TopTools_ListOfShape& aLH = !j ? myHistory->Modified(aS) : myHistory->Generated(aS);
TopTools_ListIteratorOfListOfShape itLH(aLH);
for (; itLH.More(); itLH.Next())
{
const TopoDS_Shape& aHS = itLH.Value();
TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aHS);
if (!pLOr)
pLOr = myOrigins.Bound(aHS, TopTools_ListOfShape());
if (!pLOr->Contains(aS))
pLOr->Append(aS);
}
}
}
}
//=======================================================================
//function : AssociateMaterials
//purpose : Associates the materials for the border elements
//=======================================================================
void BOPAlgo_MakeConnected::AssociateMaterials()
{
myMaterials.Clear();
// Extract all non-compound shapes from the result
TopTools_ListOfShape aLShapes;
TopTools_MapOfShape aMFence;
BOPAlgo_Tools::TreatCompound(myShape, aMFence, aLShapes);
if (aLShapes.IsEmpty())
return;
// Define the element type and the material type
TopAbs_ShapeEnum anElemType;
const TopAbs_ShapeEnum aMaterialType = aLShapes.First().ShapeType();
if (aMaterialType == TopAbs_SOLID || aMaterialType == TopAbs_COMPSOLID)
anElemType = TopAbs_FACE;
else if (aMaterialType == TopAbs_FACE || aMaterialType == TopAbs_SHELL)
anElemType = TopAbs_EDGE;
else if (aMaterialType == TopAbs_EDGE || aMaterialType == TopAbs_WIRE)
anElemType = TopAbs_VERTEX;
else
return;
TopTools_ListIteratorOfListOfShape itLS(aLShapes);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aS = itLS.Value();
const TopTools_ListOfShape& aLOr = GetOrigins(aS);
const TopoDS_Shape& aSOr = aLOr.IsEmpty() ? aS : aLOr.First();
TopExp_Explorer anExp(aS, anElemType);
for (; anExp.More(); anExp.Next())
{
const TopoDS_Shape& anElement = anExp.Current();
TopTools_ListOfShape* pLM = myMaterials.ChangeSeek(anElement);
if (!pLM)
pLM = myMaterials.Bound(anElement, TopTools_ListOfShape());
pLM->Append(aSOr);
}
}
}
//=======================================================================
//function : Update
//purpose : Updates the history, material associations and origins map
// after periodicity operations
//=======================================================================
void BOPAlgo_MakeConnected::Update()
{
// Update history
myHistory->Clear();
if (!myGlueHistory.IsNull())
myHistory->Merge(myGlueHistory);
if (!myPeriodicityMaker.History().IsNull())
myHistory->Merge(myPeriodicityMaker.History());
// Fill the map of origins
FillOrigins();
// Update the material associations after making the shape periodic
AssociateMaterials();
}
//=======================================================================
//function : MakePeriodic
//purpose : Makes the shape periodic according to the given parameters
//=======================================================================
void BOPAlgo_MakeConnected::MakePeriodic(const BOPAlgo_MakePeriodic::PeriodicityParams& theParams)
{
if (HasErrors())
return;
// Make the shape periodic
myPeriodicityMaker.Clear();
myPeriodicityMaker.SetShape(myGlued);
myPeriodicityMaker.SetPeriodicityParameters(theParams);
myPeriodicityMaker.SetRunParallel(myRunParallel);
myPeriodicityMaker.Perform();
if (myPeriodicityMaker.HasErrors())
{
// Add warning informing the user that periodicity with
// given parameters is not possible
AddWarning(new BOPAlgo_AlertUnableToMakePeriodic(myShape));
return;
}
myShape = myPeriodicityMaker.Shape();
// Update history, materials, origins
Update();
}
//=======================================================================
//function : RepeatShape
//purpose : Repeats the shape in the given direction given number of times
//=======================================================================
void BOPAlgo_MakeConnected::RepeatShape(const Standard_Integer theDirectionID,
const Standard_Integer theTimes)
{
if (HasErrors())
return;
if (myPeriodicityMaker.Shape().IsNull() || myPeriodicityMaker.HasErrors())
{
// The shape has not been made periodic yet
AddWarning(new BOPAlgo_AlertShapeIsNotPeriodic(myShape));
return;
}
// Repeat the shape
myShape = myPeriodicityMaker.RepeatShape(theDirectionID, theTimes);
// Update history, materials, origins
Update();
}
//=======================================================================
//function : ClearRepetitions
//purpose : Clears the repetitions performed on the periodic shape
// keeping the shape periodic
//=======================================================================
void BOPAlgo_MakeConnected::ClearRepetitions()
{
if (HasErrors())
return;
if (myPeriodicityMaker.Shape().IsNull() || myPeriodicityMaker.HasErrors())
{
// The shape has not been made periodic yet
AddWarning(new BOPAlgo_AlertShapeIsNotPeriodic(myShape));
return;
}
// Clear repetitions
myPeriodicityMaker.ClearRepetitions();
myShape = myPeriodicityMaker.Shape();
// Update history, materials, origins
Update();
}

View File

@@ -0,0 +1,338 @@
// Created on: 2018-03-29
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BOPAlgo_MakeConnected_HeaderFile
#define _BOPAlgo_MakeConnected_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <BOPAlgo_Options.hxx>
#include <BOPAlgo_MakePeriodic.hxx>
#include <BRepTools_History.hxx>
#include <NCollection_DataMap.hxx>
#include <TopTools_OrientedShapeMapHasher.hxx>
//! BOPAlgo_MakeConnected is the algorithm for making the touching
//! shapes connected or glued, i.e. for making the coinciding geometries
//! be topologically shared among the shapes.
//!
//! The input shapes should be of the same dimension, otherwise
//! the gluing will not make any sense.
//!
//! After the shapes are made connected, the border elements of input shapes
//! are associated with the shapes to which they belong. At that, the orientation of
//! the border element in the shape is taken into account.
//! The associations are made for the following types:
//! - For input SOLIDS, the resulting FACES are associated with the input solids;
//! - For input FACES, the resulting EDGES are associated with the input faces;
//! - For input EDGES, the resulting VERTICES are associated with the input edges.
//!
//! In frames of this algorithm the input shapes are called materials,
//! and the association process is called the material association.
//! The material association allows finding the coinciding elements for the opposite
//! input shapes. These elements will be associated to at least two materials.
//!
//! After making the shapes connected, it is possible to make the connected
//! shape periodic using the *BOPAlgo_MakePeriodic* tool.
//! After making the shape periodic, the material associations will be updated
//! to correspond to the actual state of the result shape.
//! Repetition of the periodic shape is also possible here. Material associations
//! are not going to be lost.
//!
//! The algorithm supports history of shapes modification, thus it is possible
//! to track the modification of the input shapes during the operations.
//! Additionally to standard history methods, the algorithm provides the
//! the method *GetOrigins()* which allows obtaining the input shapes from which
//! the resulting shape has been created.
//!
//! The algorithm supports the parallel processing mode, which allows faster
//! completion of the operations.
//!
//! The algorithm returns the following Error/Warning messages:
//! - *BOPAlgo_AlertTooFewArguments* - error alert is given on the attempt to run
//! the algorithm without the arguments;
//! - *BOPAlgo_AlertMultiDimensionalArguments* - error alert is given on the attempt
//! to run the algorithm on multi-dimensional arguments;
//! - *BOPAlgo_AlertUnableToGlue* - error alert is given if the gluer algorithm
//! is unable to glue the given arguments;
//! - *BOPAlgo_AlertUnableToMakePeriodic* - warning alert is given if the periodicity
//! maker is unable to make the connected shape periodic with given options;
//! - *BOPAlgo_AlertShapeIsNotPeriodic* - warning alert is given on the attempt to
//! repeat the shape before making it periodic.
//!
//! Here is the example of usage of the algorithm:
//! ~~~~
//! TopTools_ListOfShape anArguments = ...; // Shapes to make connected
//! Standard_Boolean bRunParallel = ...; // Parallel processing mode
//!
//! BOPAlgo_MakeConnected aMC; // Tool for making the shapes connected
//! aMC.SetArguments(anArguments); // Set the shapes
//! aMC.SetRunParallel(bRunParallel); // Set parallel processing mode
//! aMC.Perform(); // Perform the operation
//!
//! if (aMC.HasErrors()) // Check for the errors
//! {
//! // errors treatment
//! Standard_SStream aSStream;
//! aMC.DumpErrors(aSStream);
//! return;
//! }
//! if (aMC.HasWarnings()) // Check for the warnings
//! {
//! // warnings treatment
//! Standard_SStream aSStream;
//! aMC.DumpWarnings(aSStream);
//! }
//!
//! const TopoDS_Shape& aGluedShape = aMC.Shape(); // Connected shape
//!
//! // Checking material associations
//! TopAbs_ShapeEnum anElemType = ...; // Type of border element
//! TopExp_Explorer anExp(anArguments.First(), anElemType);
//! for (; anExp.More(); anExp.Next())
//! {
//! const TopoDS_Shape& anElement = anExp.Current();
//! const TopTools_ListOfShape& aNegativeM = aMC.MaterialsOnNegativeSide(anElement);
//! const TopTools_ListOfShape& aPositiveM = aMC.MaterialsOnPositiveSide(anElement);
//! }
//!
//! // Making the connected shape periodic
//! BOPAlgo_MakePeriodic::PeriodicityParams aParams = ...; // Options for periodicity of the connected shape
//! aMC.MakePeriodic(aParams);
//!
//! // Shape repetition after making it periodic
//! // Check if the shape has been made periodic successfully
//! if (aMC.PeriodicityTool().HasErrors())
//! {
//! // Periodicity maker error treatment
//! }
//!
//! // Shape repetition in periodic directions
//! aMC.RepeatShape(0, 2);
//!
//! const TopoDS_Shape& aShape = aMC.PeriodicShape(); // Periodic and repeated shape
//! ~~~~
//!
class BOPAlgo_MakeConnected : public BOPAlgo_Options
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructor
//! Empty constructor
BOPAlgo_MakeConnected() : BOPAlgo_Options()
{
}
public: //! @name Setters for the shapes to make connected
//! Sets the shape for making them connected.
//! @param theArgs [in] The arguments for the operation.
void SetArguments(const TopTools_ListOfShape& theArgs)
{
myArguments = theArgs;
}
//! Adds the shape to the arguments.
//! @param theS [in] One of the argument shapes.
void AddArgument(const TopoDS_Shape& theS)
{
myArguments.Append(theS);
}
//! Returns the list of arguments of the operation.
const TopTools_ListOfShape& Arguments() const
{
return myArguments;
}
public: //! @name Performing the operations
//! Performs the operation, i.e. makes the input shapes connected.
Standard_EXPORT void Perform();
public: //! @name Shape periodicity & repetition
//! Makes the connected shape periodic.
//! Repeated calls of this method overwrite the previous calls
//! working with the basis connected shape.
//! @param theParams [in] Periodic options.
Standard_EXPORT void MakePeriodic(const BOPAlgo_MakePeriodic::PeriodicityParams& theParams);
//! Performs repetition of the periodic shape in specified direction
//! required number of times.
//! @param theDirectionID [in] The direction's ID (0 for X, 1 for Y, 2 for Z);
//! @param theTimes [in] Requested number of repetitions (sign of the value defines
//! the side of the repetition direction (positive or negative)).
Standard_EXPORT void RepeatShape(const Standard_Integer theDirectionID,
const Standard_Integer theTimes);
//! Clears the repetitions performed on the periodic shape,
//! keeping the shape periodic.
Standard_EXPORT void ClearRepetitions();
//! Returns the periodicity tool.
const BOPAlgo_MakePeriodic& PeriodicityTool() const
{
return myPeriodicityMaker;
}
public: //! @name Material transitions
//! Returns the original shapes which images contain the
//! the given shape with FORWARD orientation.
//! @param theS [in] The shape for which the materials are necessary.
const TopTools_ListOfShape& MaterialsOnPositiveSide(const TopoDS_Shape& theS)
{
const TopTools_ListOfShape* pLM = myMaterials.Seek(theS.Oriented(TopAbs_FORWARD));
return (pLM ? *pLM : EmptyList());
}
//! Returns the original shapes which images contain the
//! the given shape with REVERSED orientation.
//! @param theS [in] The shape for which the materials are necessary.
const TopTools_ListOfShape& MaterialsOnNegativeSide(const TopoDS_Shape& theS)
{
const TopTools_ListOfShape* pLM = myMaterials.Seek(theS.Oriented(TopAbs_REVERSED));
return (pLM ? *pLM : EmptyList());
}
public: //! @name History methods
//! Returns the history of operations
const Handle(BRepTools_History)& History() const
{
return myHistory;
}
//! Returns the list of shapes modified from the given shape.
//! @param theS [in] The shape for which the modified shapes are necessary.
const TopTools_ListOfShape& GetModified(const TopoDS_Shape& theS)
{
return (myHistory.IsNull() ? EmptyList() : myHistory->Modified(theS));
}
//! Returns the list of original shapes from which the current shape has been created.
//! @param theS [in] The shape for which the origins are necessary.
const TopTools_ListOfShape& GetOrigins(const TopoDS_Shape& theS)
{
const TopTools_ListOfShape* pLOr = myOrigins.Seek(theS);
return (pLOr ? *pLOr : EmptyList());
}
public: //! @name Getting the result shapes
//! Returns the resulting connected shape
const TopoDS_Shape& Shape() const
{
return myGlued;
}
//! Returns the resulting periodic & repeated shape
const TopoDS_Shape& PeriodicShape() const
{
return myShape;
}
public: //! @name Clearing the contents of the algorithm from previous runs
//! Clears the contents of the algorithm.
void Clear()
{
BOPAlgo_Options::Clear();
myArguments.Clear();
myAllInputsMap.Clear();
myPeriodicityMaker.Clear();
myOrigins.Clear();
myMaterials.Clear();
if (!myGlueHistory.IsNull())
myGlueHistory->Clear();
if (!myHistory.IsNull())
myHistory->Clear();
myGlued.Nullify();
myShape.Nullify();
}
protected: //! @name Protected methods performing the operation
//! Checks the validity of input data.
Standard_EXPORT void CheckData();
//! Makes the argument shapes connected (or glued).
Standard_EXPORT void MakeConnected();
//! Associates the materials transitions for the border elements:
//! - For input Solids, associates the Faces to Solids;
//! - For input Faces, associates the Edges to Faces;
//! - For input Edges, associates the Vertices to Edges.
Standard_EXPORT void AssociateMaterials();
//! Fills the map of origins
Standard_EXPORT void FillOrigins();
//! Updates the history, material associations, origins map
//! after periodicity operations.
Standard_EXPORT void Update();
private:
//! Returns an empty list.
const TopTools_ListOfShape& EmptyList()
{
static const TopTools_ListOfShape anEmptyList;
return anEmptyList;
}
protected: //! @name Fields
// Inputs
TopTools_ListOfShape myArguments; //!< Input shapes for making them connected
TopTools_IndexedMapOfShape myAllInputsMap; //!< Map of all BRep sub-elements of the input shapes
// Tools
BOPAlgo_MakePeriodic myPeriodicityMaker; //!< Tool for making the shape periodic
// Results
NCollection_DataMap
<TopoDS_Shape,
TopTools_ListOfShape,
TopTools_OrientedShapeMapHasher> myMaterials; //!< Map of the materials associations
//! for the border elements
TopTools_DataMapOfShapeListOfShape myOrigins; //!< Map of origins
//! (allows tracking the shape's ancestors)
Handle(BRepTools_History) myGlueHistory; //!< Gluing History
Handle(BRepTools_History) myHistory; //!< Final History of shapes modifications
//! (including making the shape periodic and repetitions)
TopoDS_Shape myGlued; //!< The resulting connected (glued) shape
TopoDS_Shape myShape; //!< The resulting shape
};
#endif // _BOPAlgo_MakeConnected_HeaderFile

View File

@@ -0,0 +1,617 @@
// Created on: 2018-03-16
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPAlgo_MakePeriodic.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <Bnd_Box.hxx>
#include <BOPAlgo_Builder.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Splitter.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pln.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
// Periodic/Trim/Repeat directions
static const gp_Dir MY_DIRECTIONS[3] = { gp::DX(),
gp::DY(),
gp::DZ() };
//=======================================================================
//function : Perform
//purpose : Performs the operation
//=======================================================================
void BOPAlgo_MakePeriodic::Perform()
{
// Check the validity of input data
CheckData();
if (HasErrors())
return;
// Trim the shape to fit to the required period in
// required periodic directions
Trim();
if (HasErrors())
return;
// Make the shape identical on the opposite sides in
// required periodic directions
MakeIdentical();
if (HasErrors())
return;
}
//=======================================================================
//function : CheckData
//purpose : Checks the validity of input data
//=======================================================================
void BOPAlgo_MakePeriodic::CheckData()
{
if ( (!IsXPeriodic() || XPeriod() < Precision::Confusion())
&& (!IsYPeriodic() || YPeriod() < Precision::Confusion())
&& (!IsZPeriodic() || ZPeriod() < Precision::Confusion()))
{
// Add error informing the user that no periodicity is required
// or no valid period is set.
AddError(new BOPAlgo_AlertNoPeriodicityRequired());
return;
}
}
//=======================================================================
//function : AddToShape
//purpose : Adds the shape <theWhat> to the shape <theWhere>
//=======================================================================
static void AddToShape(const TopoDS_Shape& theWhat,
TopoDS_Shape& theWhere)
{
if (theWhere.IsNull())
BRep_Builder().MakeCompound(TopoDS::Compound(theWhere));
BRep_Builder().Add(theWhere, theWhat);
}
//=======================================================================
//function : AddToShape
//purpose : Adds the shape in the list <theLWhat> to the shape <theWhere>
//=======================================================================
static void AddToShape(const TopTools_ListOfShape& theLWhat,
TopoDS_Shape& theWhere)
{
TopTools_ListIteratorOfListOfShape it(theLWhat);
for (; it.More(); it.Next())
AddToShape(it.Value(), theWhere);
}
//=======================================================================
//function : Trim
//purpose : Make the trim of the shape to fit to the periodic bounds.
//=======================================================================
void BOPAlgo_MakePeriodic::Trim()
{
// Check if trim is required at all
if (IsInputXTrimmed() &&
IsInputYTrimmed() &&
IsInputZTrimmed())
return;
// Compute bounding box for the shape to use it as a starting
// volume for trimming. If required, the volume will be modified
// to the requested trimming size in requested directions.
Bnd_Box aBox;
BRepBndLib::Add(myInputShape, aBox);
// Enlarge box to avoid overlapping with the shape
aBox.Enlarge(0.1 * sqrt(aBox.SquareExtent()));
// Get Corner points of the bounding box
gp_Pnt aPMin = aBox.CornerMin();
gp_Pnt aPMax = aBox.CornerMax();
// Update corner points according to the requested trim parameters
for (Standard_Integer i = 0; i < 3; ++i)
{
if (IsInputTrimmed(i))
continue;
aPMin.SetCoord(i + 1, PeriodFirst(i));
aPMax.SetCoord(i + 1, PeriodFirst(i) + Period(i));
}
// Build Trimming solid using corner points
BRepPrimAPI_MakeBox aMBox(aPMin, aPMax);
const TopoDS_Shape& aTrimBox = aMBox.Solid();
// Perform trimming of the shape by solid
BRepAlgoAPI_Common aCommon;
// Set Object
TopTools_ListOfShape anObj;
anObj.Append(myInputShape);
aCommon.SetArguments(anObj);
// Set Tool
TopTools_ListOfShape aTool;
aTool.Append(aTrimBox);
aCommon.SetTools(aTool);
// Set the parallel processing mode
aCommon.SetRunParallel(myRunParallel);
// Build
aCommon.Build();
if (aCommon.HasErrors())
{
// Unable to trim the shape
// Merge errors from Common operation
myReport->Merge(aCommon.GetReport());
// Add new error saving the shapes for analysis
TopoDS_Compound aWS;
AddToShape(myInputShape, aWS);
AddToShape(aTrimBox, aWS);
AddError(new BOPAlgo_AlertUnableToTrim(aWS));
return;
}
// Get the trimmed shape
myShape = aCommon.Shape();
// Fill the History for the object only
mySplitHistory = new BRepTools_History();
mySplitHistory->Merge(anObj, aCommon);
}
//=======================================================================
//function : MakeIdentical
//purpose : Make the shape look the same on the opposite sides in the
// required periodic directions.
//=======================================================================
void BOPAlgo_MakePeriodic::MakeIdentical()
{
if (myShape.IsNull())
myShape = myInputShape;
if (mySplitHistory.IsNull())
mySplitHistory = new BRepTools_History;
// Split the negative side of the shape with the geometry
// located on the positive side
SplitNegative();
if (HasErrors())
return;
// Split the positive side of the shape with the geometry
// located on the negative side.
// Make sure that the opposite sides have identical geometries.
// Make associations between identical opposite shapes.
SplitPositive();
myHistory = new BRepTools_History();
myHistory->Merge(mySplitHistory);
}
//=======================================================================
//function : SplitNegative
//purpose : Split the negative side of the shape with the geometry
// located on the positive side.
//=======================================================================
void BOPAlgo_MakePeriodic::SplitNegative()
{
// Copy geometry from positive side of the shape to the negative first.
// So, translate the shape in negative periodic directions only.
//
// To avoid conflicts when copying geometries from positive periodic sides
// perform split of each periodic side in a separate operation.
for (Standard_Integer i = 0; i < 3; ++i)
{
if (!IsPeriodic(i))
continue;
// Translate the shape to the negative side
gp_Trsf aNegTrsf;
aNegTrsf.SetTranslationPart(Period(i) * MY_DIRECTIONS[i].Reversed());
BRepBuilderAPI_Transform aNegT(myShape, aNegTrsf, Standard_False);
// Split the negative side of the shape.
TopTools_ListOfShape aTools;
aTools.Append(aNegT.Shape());
SplitShape(aTools, mySplitHistory);
}
}
//=======================================================================
//function : AddTwin
//purpose : Associates the shape <theS> with the shape <theTwin> in the map.
//=======================================================================
static void AddTwin(const TopoDS_Shape& theS,
const TopoDS_Shape& theTwin,
TopTools_DataMapOfShapeListOfShape& theMap)
{
TopTools_ListOfShape *aTwins = theMap.ChangeSeek(theS);
if (!aTwins)
{
theMap.Bound(theS, TopTools_ListOfShape())->Append(theTwin);
return;
}
// Check if the twin shape is not yet present in the list
TopTools_ListIteratorOfListOfShape itLT(*aTwins);
for (; itLT.More(); itLT.Next())
{
if (theTwin.IsSame(itLT.Value()))
break;
}
if (!itLT.More())
aTwins->Append(theTwin);
}
//=======================================================================
//function : SplitPositive
//purpose : Split the positive side of the shape with the geometry of the
// negative side. Associate the identical opposite sub-shapes.
//=======================================================================
void BOPAlgo_MakePeriodic::SplitPositive()
{
// Prepare map of the sub-shapes of the input shape to make
// associations of the opposite shapes
TopTools_IndexedMapOfShape aSubShapesMap;
TopExp::MapShapes(myShape, aSubShapesMap);
const Standard_Integer aNbS = aSubShapesMap.Extent();
// Translate the shape to the positive periodic directions to make the
// shapes look identical on the opposite sides.
TopTools_ListOfShape aTools;
// Remember the history of shapes translation
TopTools_IndexedDataMapOfShapeListOfShape aTranslationHistMap;
// Make translations for all periodic directions
for (Standard_Integer i = 0; i < 3; ++i)
{
if (!IsPeriodic(i))
continue;
// Translate the shape to the positive side
gp_Trsf aPosTrsf;
aPosTrsf.SetTranslationPart(Period(i) * MY_DIRECTIONS[i]);
BRepBuilderAPI_Transform aTranslator(myShape, aPosTrsf, Standard_False);
aTools.Append(aTranslator.Shape());
// Fill the translation history map
for (Standard_Integer j = 1; j <= aNbS; ++j)
{
const TopoDS_Shape& aS = aSubShapesMap(j);
if (BRepTools_History::IsSupportedType(aS))
{
const TopTools_ListOfShape& aSM = aTranslator.Modified(aS);
TopTools_ListOfShape* pTS = aTranslationHistMap.ChangeSeek(aS);
if (!pTS)
pTS = &aTranslationHistMap(aTranslationHistMap.Add(aS, TopTools_ListOfShape()));
pTS->Append(aSM.First());
}
}
}
// Keep the split shape history and history of tools modifications
// during the split for making association of the opposite identical shapes
Handle(BRepTools_History) aSplitShapeHist = new BRepTools_History,
aSplitToolsHist = new BRepTools_History;
// Split the positive side of the shape
SplitShape(aTools, aSplitShapeHist, aSplitToolsHist);
if (HasErrors())
return;
mySplitHistory->Merge(aSplitShapeHist);
// Make associations between identical opposite sub-shapes
const Standard_Integer aNbSH = aTranslationHistMap.Extent();
for (Standard_Integer i = 1; i <= aNbSH; ++i)
{
const TopoDS_Shape* pS = &aTranslationHistMap.FindKey(i);
const TopTools_ListOfShape& aSIm = aSplitShapeHist->Modified(*pS);
if (aSIm.Extent() == 1)
pS = &aSIm.First();
else if (aSIm.Extent() > 1)
continue;
const TopTools_ListOfShape& aLTranslated = aTranslationHistMap(i);
TopTools_ListIteratorOfListOfShape itLT(aLTranslated);
for (; itLT.More(); itLT.Next())
{
const TopoDS_Shape& aT = itLT.Value();
// Get shapes modifications during the split
const TopTools_ListOfShape& aTSplits = aSplitToolsHist->Modified(aT);
// Associate the shapes to each other
TopTools_ListIteratorOfListOfShape itSp(aTSplits);
for (; itSp.More(); itSp.Next())
{
const TopoDS_Shape& aSp = itSp.Value();
AddTwin(*pS, aSp, myTwins);
AddTwin(aSp, *pS, myTwins);
}
}
}
}
//=======================================================================
//function : SplitShape
//purpose : Splits the shape by the given tools
//=======================================================================
void BOPAlgo_MakePeriodic::SplitShape(const TopTools_ListOfShape& theTools,
Handle(BRepTools_History) theSplitShapeHistory,
Handle(BRepTools_History) theSplitToolsHistory)
{
// Make sure that the geometry from the tools will be copied to the split
// shape. For that, the tool shapes should be given to the Boolean Operations
// algorithm before the shape itself. This will make all coinciding parts
// use the geometry of the first argument.
// Intersection tool for passing ordered arguments
BOPAlgo_PaveFiller anIntersector;
anIntersector.SetArguments(theTools);
// Add the shape
anIntersector.AddArgument(myShape);
// Use gluing to speed-up intersections
anIntersector.SetGlue(BOPAlgo_GlueShift);
// Use safe input mode, to avoid reusing geometry of the shape
anIntersector.SetNonDestructive(Standard_True);
// Set parallel processing mode
anIntersector.SetRunParallel(myRunParallel);
// Perform Intersection of the arguments
anIntersector.Perform();
// Check for the errors
if (anIntersector.HasErrors())
{
// Unable to split the shape on opposite sides
// Copy the intersection errors
myReport->Merge(anIntersector.GetReport());
// Add new error saving the shapes for analysis
TopoDS_Compound aWS;
AddToShape(theTools, aWS);
AddToShape(myShape, aWS);
AddError(new BOPAlgo_AlertUnableToMakeIdentical(aWS));
return;
}
// Perform the splitting of the shape with the precomputed intersection results
BRepAlgoAPI_Splitter aSplitter(anIntersector);
// Set Object
TopTools_ListOfShape anObj;
anObj.Append(myShape);
aSplitter.SetArguments(anObj);
// Set Tools
aSplitter.SetTools(theTools);
// Use Gluing
aSplitter.SetGlue(BOPAlgo_GlueShift);
// Set parallel processing mode
aSplitter.SetRunParallel(myRunParallel);
// Perform splitting
aSplitter.Build();
// Check for the errors
if (aSplitter.HasErrors())
{
// Unable to split the shape on opposite sides
// Copy the splitter errors
myReport->Merge(aSplitter.GetReport());
// Add new error saving the shape for analysis
TopoDS_Compound aWS;
AddToShape(theTools, aWS);
AddToShape(myShape, aWS);
AddError(new BOPAlgo_AlertUnableToMakeIdentical(aWS));
return;
}
// Get the split shape
myShape = aSplitter.Shape();
// Remember the split history
if (!theSplitShapeHistory.IsNull())
theSplitShapeHistory->Merge(anObj, aSplitter);
if (!theSplitToolsHistory.IsNull())
theSplitToolsHistory->Merge(theTools, aSplitter);
}
//=======================================================================
//function : RepeatShape
//purpose : Repeats the shape in the required periodic direction
//=======================================================================
const TopoDS_Shape& BOPAlgo_MakePeriodic::RepeatShape(const Standard_Integer theDir,
const Standard_Integer theTimes)
{
if (myRepeatedShape.IsNull())
myRepeatedShape = myShape;
if (!IsPeriodic(theDir))
return myRepeatedShape;
if (theTimes == 0)
return myRepeatedShape;
// Get the shape's period in the required direction
const Standard_Integer id = BOPAlgo_MakePeriodic::ToDirectionID(theDir);
if (myRepeatPeriod[id] < Precision::Confusion())
myRepeatPeriod[id] = Period(id);
const Standard_Real aPeriod = myRepeatPeriod[id];
// Coefficient to define in which direction the repetition will be performed:
// theTimes is positive - in positive direction;
// theTimes is negative - in negative direction.
const Standard_Integer iDir = theTimes > 0 ? 1 : -1;
// Create the translation history - all translated shapes will be
// created as Generated from the shape.
BRepTools_History aTranslationHistory;
TopTools_IndexedMapOfShape aSubShapesMap;
TopExp::MapShapes(myRepeatedShape, aSubShapesMap);
const Standard_Integer aNbS = aSubShapesMap.Extent();
// Add shapes for gluing
TopTools_ListOfShape aShapes;
// Add the shape itself
aShapes.Append(myRepeatedShape);
for (Standard_Integer i = 1; i <= aNbS; ++i)
{
const TopoDS_Shape& aS = aSubShapesMap(i);
if (BRepTools_History::IsSupportedType(aS))
aTranslationHistory.AddGenerated(aS, aS);
}
// Create translated copies of the shape
for (Standard_Integer i = 1; i <= Abs(theTimes); ++i)
{
gp_Trsf aTrsf;
aTrsf.SetTranslationPart(iDir * i * aPeriod * MY_DIRECTIONS[id]);
BRepBuilderAPI_Transform aTranslator(myRepeatedShape, aTrsf, Standard_False);
aShapes.Append(aTranslator.Shape());
// Fill the translation history
for (Standard_Integer j = 1; j <= aNbS; ++j)
{
const TopoDS_Shape& aS = aSubShapesMap(j);
if (BRepTools_History::IsSupportedType(aS))
{
const TopTools_ListOfShape& aLT = aTranslator.Modified(aS);
aTranslationHistory.AddGenerated(aS, aLT.First());
}
}
}
// Update the history with the translation History
myHistory->Merge(aTranslationHistory);
// Glue the translated shapes all together
BOPAlgo_Builder aGluer;
aGluer.SetArguments(aShapes);
// Avoid intersections of the sub-shapes
aGluer.SetGlue(BOPAlgo_GlueFull);
// Set parallel processing mode
aGluer.SetRunParallel(myRunParallel);
// Perform gluing
aGluer.Perform();
if (aGluer.HasErrors())
{
// Repetition in this direction is not possible
// Add warning saving the shapes for analysis
TopoDS_Compound aWS;
AddToShape(aShapes, aWS);
AddWarning(new BOPAlgo_AlertUnableToRepeat(aWS));
return myRepeatedShape;
}
// Get glued shape
myRepeatedShape = aGluer.Shape();
// Update repetition period for the next repetitions
myRepeatPeriod[id] += Abs(theTimes) * myRepeatPeriod[id];
// Update history with the Gluing history
BRepTools_History aGluingHistory(aShapes, aGluer);
myHistory->Merge(aGluingHistory);
// Update the map of twins after repetition
UpdateTwins(aTranslationHistory, aGluingHistory);
return myRepeatedShape;
}
//=======================================================================
//function : UpdateTwins
//purpose : Updates the map of twins after repetition
//=======================================================================
void BOPAlgo_MakePeriodic::UpdateTwins(const BRepTools_History& theTranslationHistory,
const BRepTools_History& theGluingHistory)
{
if (myTwins.IsEmpty())
return;
if (myRepeatedTwins.IsEmpty())
myRepeatedTwins = myTwins;
// New twins
TopTools_DataMapOfShapeListOfShape aNewTwinsMap;
// Fence map to avoid repeated fill for the twins
TopTools_MapOfShape aMTwinsDone;
// Update the map of twins with the new repeated shapes
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itDMap(myRepeatedTwins);
for (; itDMap.More(); itDMap.Next())
{
const TopoDS_Shape& aS = itDMap.Key();
aMTwinsDone.Add(aS);
const TopTools_ListOfShape& aLTwins = itDMap.Value();
// Check if the twins have not been already processed
TopTools_ListIteratorOfListOfShape itLT(aLTwins);
for (; itLT.More(); itLT.Next())
{
if (aMTwinsDone.Contains(itLT.Value()))
break;
}
if (itLT.More())
// Group of twins has already been processed
continue;
// All shapes generated from the shape itself and generated
// from its twins will be the new twins for the shape
TopTools_IndexedMapOfShape aNewGroup;
itLT.Initialize(aLTwins);
for (Standard_Boolean bShape = Standard_True; itLT.More();)
{
const TopoDS_Shape& aTwin = bShape ? aS : itLT.Value();
const TopTools_ListOfShape& aLG = theTranslationHistory.Generated(aTwin);
TopTools_ListIteratorOfListOfShape itLG(aLG);
for (; itLG.More(); itLG.Next())
{
const TopoDS_Shape& aG = itLG.Value();
const TopTools_ListOfShape& aLM = theGluingHistory.Modified(aG);
if (aLM.IsEmpty())
aNewGroup.Add(aG);
else
{
TopTools_ListIteratorOfListOfShape itLM(aLM);
for (; itLM.More(); itLM.Next())
aNewGroup.Add(itLM.Value());
}
}
if (bShape)
bShape = Standard_False;
else
itLT.Next();
}
// Associate the twins to each other
const Standard_Integer aNbTwins = aNewGroup.Extent();
for (Standard_Integer i = 1; i <= aNbTwins; ++i)
{
TopTools_ListOfShape* pTwins = aNewTwinsMap.Bound(aNewGroup(i), TopTools_ListOfShape());
for (Standard_Integer j = 1; j <= aNbTwins; ++j)
if (i != j) pTwins->Append(aNewGroup(j));
}
}
myRepeatedTwins = aNewTwinsMap;
}

View File

@@ -0,0 +1,603 @@
// Created on: 2018-03-16
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BOPAlgo_MakePeriodic_HeaderFile
#define _BOPAlgo_MakePeriodic_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <BOPAlgo_Options.hxx>
#include <BRepTools_History.hxx>
#include <Standard_Boolean.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
//! BOPAlgo_MakePeriodic is the tool for making an arbitrary shape periodic
//! in 3D space in specified directions.
//!
//! Periodicity of the shape means that the shape can be repeated in any
//! periodic direction any number of times without creation of the new
//! geometry or splits.
//!
//! The idea is to make the shape look identical on the opposite sides of the
//! periodic directions, so when translating the copy of a shape on the period
//! there will be no coinciding parts of different dimensions.
//!
//! If necessary the algorithm will trim the shape to fit it into the
//! requested period by splitting it by the planes limiting the shape's
//! requested period.
//!
//! For making the shape periodic in certain direction the algorithm performs
//! the following steps:
//! * Creates the copy of the shape and moves it on the period into negative
//! side of the requested direction;
//! * Splits the negative side of the shape by the moved copy, ensuring copying
//! of the geometry from positive side to negative;
//! * Creates the copy of the shape (with already split negative side) and moves
//! it on the period into the positive side of the requested direction;
//! * Splits the positive side of the shape by the moved copy, ensuring copying
//! of the geometry from negative side to positive.
//!
//! The algorithm also associates the identical (or twin) shapes located
//! on the opposite sides of the result shape.
//! Using the *GetTwins()* method it is possible to get the twin shapes from
//! the opposite sides.
//!
//! Algorithm also provides the methods to repeat the periodic shape in
//! periodic directions. The subsequent repetitions are performed on the
//! repeated shape, thus repeating the shape two times in X direction will
//! create result in three shapes (original plus two copies).
//! Single subsequent repetition will result already in 6 shapes.
//! The repetitions can be cleared and started over.
//!
//! The algorithm supports History of shapes modifications, thus
//! it is possible to track how the shape has been changed to make it periodic
//! and what new shapes have been created during repetitions.
//!
//! The algorithm supports the parallel processing mode, which allows faster
//! completion of the operations.
//!
//! The algorithm supports the Error/Warning system and returns the following alerts:
//! - *BOPAlgo_AlertNoPeriodicityRequired* - Error alert is given if no periodicity
//! has been requested in any direction;
//! - *BOPAlgo_AlertUnableToTrim* - Error alert is given if the trimming of the shape
//! for fitting it into requested period has failed;
//! - *BOPAlgo_AlertUnableToMakeIdentical* - Error alert is given if splitting of the
//! shape by its moved copies has failed;
//! - *BOPAlgo_AlertUnableToRepeat* - Warning alert is given if the gluing of the repeated
//! shapes has failed.
//!
//! Example of usage of the algorithm:
//! ~~~~
//! TopoDS_Shape aShape = ...; // The shape to make periodic
//! Standard_Boolean bMakeXPeriodic = ...; // Flag for making or not the shape periodic in X direction
//! Standard_Real aXPeriod = ...; // X period for the shape
//! Standard_Boolean isXTrimmed = ...; // Flag defining whether it is necessary to trimming
//! // the shape to fit to X period
//! Standard_Real aXFirst = ...; // Start of the X period
//! // (really necessary only if the trimming is requested)
//! Standard_Boolean bRunParallel = ...; // Parallel processing mode or single
//!
//! BOPAlgo_MakePeriodic aPeriodicityMaker; // Periodicity maker
//! aPeriodicityMaker.SetShape(aShape); // Set the shape
//! aPeriodicityMaker.MakeXPeriodic(bMakePeriodic, aXPeriod); // Making the shape periodic in X direction
//! aPeriodicityMaker.SetTrimmed(isXTrimmed, aXFirst); // Trim the shape to fit X period
//! aPeriodicityMaker.SetRunParallel(bRunParallel); // Set the parallel processing mode
//! aPeriodicityMaker.Perform(); // Performing the operation
//!
//! if (aPeriodicityMaker.HasErrors()) // Check for the errors
//! {
//! // errors treatment
//! Standard_SStream aSStream;
//! aPeriodicityMaker.DumpErrors(aSStream);
//! return;
//! }
//! if (aPeriodicityMaker.HasWarnings()) // Check for the warnings
//! {
//! // warnings treatment
//! Standard_SStream aSStream;
//! aPeriodicityMaker.DumpWarnings(aSStream);
//! }
//! const TopoDS_Shape& aPeriodicShape = aPeriodicityMaker.Shape(); // Result periodic shape
//!
//!
//! aPeriodicityMaker.XRepeat(2); // Making repetitions
//! const TopoDS_Shape& aRepeat = aPeriodicityMaker.RepeatedShape(); // Getting the repeated shape
//! aPeriodicityMaker.ClearRepetitions(); // Clearing the repetitions
//! ~~~~
//!
class BOPAlgo_MakePeriodic : public BOPAlgo_Options
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructor
//! Empty constructor
BOPAlgo_MakePeriodic() : BOPAlgo_Options()
{
myRepeatPeriod[0] = myRepeatPeriod[1] = myRepeatPeriod[2] = 0.0;
}
public: //! @name Setting the shape to make it periodic
//! Sets the shape to make it periodic.
//! @param theShape [in] The shape to make periodic.
void SetShape(const TopoDS_Shape& theShape)
{
myInputShape = theShape;
}
public: //! @name Definition of the structure to keep all periodicity parameters
//! Structure to keep all periodicity parameters:
struct PeriodicityParams
{
PeriodicityParams()
{
Clear();
}
//! Returns all previously set parameters to default values
void Clear()
{
myPeriodic[0] = myPeriodic[1] = myPeriodic[2] = Standard_False;
myPeriod[0] = myPeriod[1] = myPeriod[2] = 0.0;
myIsTrimmed[0] = myIsTrimmed[1] = myIsTrimmed[2] = Standard_True;
myPeriodFirst[0] = myPeriodFirst[1] = myPeriodFirst[2] = 0.0;
}
Standard_Boolean myPeriodic[3]; //!< Array of flags defining whether the shape should be
//! periodic in XYZ directions
Standard_Real myPeriod[3]; //!< Array of XYZ period values. Defining the period for any
//! direction the corresponding flag for that direction in
//! myPeriodic should be set to true
Standard_Boolean myIsTrimmed[3]; //!< Array of flags defining whether the input shape has to be
//! trimmed to fit the required period in the required direction
Standard_Real myPeriodFirst[3]; //!< Array of start parameters of the XYZ periods: required for trimming
};
public: //! @name Setters/Getters for periodicity parameters structure
//! Sets the periodicity parameters.
//! @param theParams [in] Periodicity parameters
void SetPeriodicityParameters(const PeriodicityParams& theParams)
{
myPeriodicityParams = theParams;
}
const PeriodicityParams& PeriodicityParameters() const
{
return myPeriodicityParams;
}
public: //! @name Methods for setting/getting periodicity info using ID as a direction
//! Sets the flag to make the shape periodic in specified direction:
//! - 0 - X direction;
//! - 1 - Y direction;
//! - 2 - Z direction.
//!
//! @param theDirectionID [in] The direction's ID;
//! @param theIsPeriodic [in] Flag defining periodicity in given direction;
//! @param thePeriod [in] Required period in given direction.
void MakePeriodic(const Standard_Integer theDirectionID,
const Standard_Boolean theIsPeriodic,
const Standard_Real thePeriod = 0.0)
{
Standard_Integer id = ToDirectionID(theDirectionID);
myPeriodicityParams.myPeriodic[id] = theIsPeriodic;
myPeriodicityParams.myPeriod[id] = theIsPeriodic ? thePeriod : 0.0;
}
//! Returns the info about Periodicity of the shape in specified direction.
//! @param theDirectionID [in] The direction's ID.
Standard_Boolean IsPeriodic(const Standard_Integer theDirectionID) const
{
return myPeriodicityParams.myPeriodic[ToDirectionID(theDirectionID)];
}
//! Returns the Period of the shape in specified direction.
//! @param theDirectionID [in] The direction's ID.
Standard_Real Period(const Standard_Integer theDirectionID) const
{
Standard_Integer id = ToDirectionID(theDirectionID);
return myPeriodicityParams.myPeriodic[id] ? myPeriodicityParams.myPeriod[id] : 0.0;
}
public: //! @name Named methods for setting/getting info about shape's periodicity
//! Sets the flag to make the shape periodic in X direction.
//! @param theIsPeriodic [in] Flag defining periodicity in X direction;
//! @param thePeriod [in] Required period in X direction.
void MakeXPeriodic(const Standard_Boolean theIsPeriodic,
const Standard_Real thePeriod = 0.0)
{
MakePeriodic(0, theIsPeriodic, thePeriod);
}
//! Returns the info about periodicity of the shape in X direction.
Standard_Boolean IsXPeriodic() const { return IsPeriodic(0); }
//! Returns the XPeriod of the shape
Standard_Real XPeriod() const { return Period(0); }
//! Sets the flag to make the shape periodic in Y direction.
//! @param theIsPeriodic [in] Flag defining periodicity in Y direction;
//! @param thePeriod [in] Required period in Y direction.
void MakeYPeriodic(const Standard_Boolean theIsPeriodic,
const Standard_Real thePeriod = 0.0)
{
MakePeriodic(1, theIsPeriodic, thePeriod);
}
//! Returns the info about periodicity of the shape in Y direction.
Standard_Boolean IsYPeriodic() const { return IsPeriodic(1); }
//! Returns the YPeriod of the shape.
Standard_Real YPeriod() const { return Period(1); }
//! Sets the flag to make the shape periodic in Z direction.
//! @param theIsPeriodic [in] Flag defining periodicity in Z direction;
//! @param thePeriod [in] Required period in Z direction.
void MakeZPeriodic(const Standard_Boolean theIsPeriodic,
const Standard_Real thePeriod = 0.0)
{
MakePeriodic(2, theIsPeriodic, thePeriod);
}
//! Returns the info about periodicity of the shape in Z direction.
Standard_Boolean IsZPeriodic() const { return IsPeriodic(2); }
//! Returns the ZPeriod of the shape.
Standard_Real ZPeriod() const { return Period(2); }
public: //! @name Methods for setting/getting trimming info taking Direction ID as a parameter
//! Defines whether the input shape is already trimmed in specified direction
//! to fit the period in this direction.
//! Direction is defined by an ID:
//! - 0 - X direction;
//! - 1 - Y direction;
//! - 2 - Z direction.
//!
//! If the shape is not trimmed it is required to set the first parameter
//! of the period in that direction.
//! The algorithm will make the shape fit into the period.
//!
//! Before calling this method, the shape has to be set to be periodic in this direction.
//!
//! @param theDirectionID [in] The direction's ID;
//! @param theIsTrimmed [in] The flag defining trimming of the shape in given direction;
//! @param theFirst [in] The first periodic parameter in the given direction.
void SetTrimmed(const Standard_Integer theDirectionID,
const Standard_Boolean theIsTrimmed,
const Standard_Real theFirst = 0.0)
{
Standard_Integer id = ToDirectionID(theDirectionID);
if (IsPeriodic(id))
{
myPeriodicityParams.myIsTrimmed[id] = theIsTrimmed;
myPeriodicityParams.myPeriodFirst[id] = !theIsTrimmed ? theFirst : 0.0;
}
}
//! Returns whether the input shape was trimmed in the specified direction.
//! @param theDirectionID [in] The direction's ID.
Standard_Boolean IsInputTrimmed(const Standard_Integer theDirectionID) const
{
return myPeriodicityParams.myIsTrimmed[ToDirectionID(theDirectionID)];
}
//! Returns the first periodic parameter in the specified direction.
//! @param theDirectionID [in] The direction's ID.
Standard_Real PeriodFirst(const Standard_Integer theDirectionID) const
{
Standard_Integer id = ToDirectionID(theDirectionID);
return !myPeriodicityParams.myIsTrimmed[id] ? myPeriodicityParams.myPeriodFirst[id] : 0.0;
}
public: //! @name Named methods for setting/getting trimming info
//! Defines whether the input shape is already trimmed in X direction
//! to fit the X period. If the shape is not trimmed it is required
//! to set the first parameter for the X period.
//! The algorithm will make the shape fit into the period.
//!
//! Before calling this method, the shape has to be set to be periodic in this direction.
//!
//! @param theIsTrimmed [in] Flag defining whether the shape is already trimmed
//! in X direction to fit the X period;
//! @param theFirst [in] The first X periodic parameter.
void SetXTrimmed(const Standard_Boolean theIsTrimmed,
const Standard_Boolean theFirst = 0.0)
{
SetTrimmed(0, theIsTrimmed, theFirst);
}
//! Returns whether the input shape was already trimmed for X period.
Standard_Boolean IsInputXTrimmed() const
{
return IsInputTrimmed(0);
}
//! Returns the first parameter for the X period.
Standard_Real XPeriodFirst() const
{
return PeriodFirst(0);
}
//! Defines whether the input shape is already trimmed in Y direction
//! to fit the Y period. If the shape is not trimmed it is required
//! to set the first parameter for the Y period.
//! The algorithm will make the shape fit into the period.
//!
//! Before calling this method, the shape has to be set to be periodic in this direction.
//!
//! @param theIsTrimmed [in] Flag defining whether the shape is already trimmed
//! in Y direction to fit the Y period;
//! @param theFirst [in] The first Y periodic parameter.
void SetYTrimmed(const Standard_Boolean theIsTrimmed,
const Standard_Boolean theFirst = 0.0)
{
SetTrimmed(1, theIsTrimmed, theFirst);
}
//! Returns whether the input shape was already trimmed for Y period.
Standard_Boolean IsInputYTrimmed() const
{
return IsInputTrimmed(1);
}
//! Returns the first parameter for the Y period.
Standard_Real YPeriodFirst() const
{
return PeriodFirst(1);
}
//! Defines whether the input shape is already trimmed in Z direction
//! to fit the Z period. If the shape is not trimmed it is required
//! to set the first parameter for the Z period.
//! The algorithm will make the shape fit into the period.
//!
//! Before calling this method, the shape has to be set to be periodic in this direction.
//!
//! @param theIsTrimmed [in] Flag defining whether the shape is already trimmed
//! in Z direction to fit the Z period;
//! @param theFirst [in] The first Z periodic parameter.
void SetZTrimmed(const Standard_Boolean theIsTrimmed,
const Standard_Boolean theFirst = 0.0)
{
SetTrimmed(2, theIsTrimmed, theFirst);
}
//! Returns whether the input shape was already trimmed for Z period.
Standard_Boolean IsInputZTrimmed() const
{
return IsInputTrimmed(2);
}
//! Returns the first parameter for the Z period.
Standard_Real ZPeriodFirst() const
{
return PeriodFirst(2);
}
public: //! @name Performing the operation
//! Makes the shape periodic in necessary directions
Standard_EXPORT void Perform();
public: //! @name Using the algorithm to repeat the shape
//! Performs repetition of the shape in specified direction
//! required number of times.
//! Negative value of times means that the repetition should
//! be perform in negative direction.
//! Makes the repeated shape a base for following repetitions.
//!
//! @param theDirectionID [in] The direction's ID;
//! @param theTimes [in] Requested number of repetitions.
Standard_EXPORT const TopoDS_Shape& RepeatShape(const Standard_Integer theDirectionID,
const Standard_Integer theTimes);
//! Repeats the shape in X direction specified number of times.
//! Negative value of times means that the repetition should be
//! perform in negative X direction.
//! Makes the repeated shape a base for following repetitions.
//!
//! @param theTimes [in] Requested number of repetitions.
const TopoDS_Shape& XRepeat(const Standard_Integer theTimes)
{
return RepeatShape(0, theTimes);
}
//! Repeats the shape in Y direction specified number of times.
//! Negative value of times means that the repetition should be
//! perform in negative Y direction.
//! Makes the repeated shape a base for following repetitions.
//!
//! @param theTimes [in] Requested number of repetitions.
const TopoDS_Shape& YRepeat(const Standard_Integer theTimes)
{
return RepeatShape(1, theTimes);
}
//! Repeats the shape in Z direction specified number of times.
//! Negative value of times means that the repetition should be
//! perform in negative Z direction.
//! Makes the repeated shape a base for following repetitions.
//!
//! @param theTimes [in] Requested number of repetitions.
const TopoDS_Shape& ZRepeat(const Standard_Integer theTimes)
{
return RepeatShape(2, theTimes);
}
public: //! @name Starting the repetitions over
//! Returns the repeated shape
const TopoDS_Shape& RepeatedShape() const { return myRepeatedShape; }
//! Clears all performed repetitions.
//! The next repetition will be performed on the base shape.
void ClearRepetitions()
{
myRepeatPeriod[0] = myRepeatPeriod[1] = myRepeatPeriod[2] = 0.0;
myRepeatedShape.Nullify();
myRepeatedTwins.Clear();
if (!myHistory.IsNull())
{
myHistory->Clear();
if (!mySplitHistory.IsNull())
myHistory->Merge(mySplitHistory);
}
}
public: //! @name Obtaining the result shape
//! Returns the resulting periodic shape
const TopoDS_Shape& Shape() const { return myShape; }
public: //! @name Getting the identical shapes
//! Returns the identical shapes for the given shape located
//! on the opposite periodic side.
//! Returns empty list in case the shape has no twin.
//!
//! @param theS [in] Shape to get the twins for.
const TopTools_ListOfShape& GetTwins(const TopoDS_Shape& theS) const
{
static TopTools_ListOfShape empty;
const TopTools_ListOfShape* aTwins =
myRepeatedTwins.IsEmpty() ? myTwins.Seek(theS) : myRepeatedTwins.Seek(theS);
return (aTwins ? *aTwins : empty);
}
public: //! @name Getting the History of the algorithm
//! Returns the History of the algorithm
const Handle(BRepTools_History)& History() const
{
return myHistory;
}
public: //! @name Clearing the algorithm from previous runs
//! Clears the algorithm from previous runs
void Clear()
{
BOPAlgo_Options::Clear();
myPeriodicityParams.Clear();
myShape.Nullify();
if (!mySplitHistory.IsNull())
mySplitHistory->Clear();
if (!myHistory.IsNull())
myHistory->Clear();
ClearRepetitions();
}
public: //! @name Conversion of the integer to ID of periodic direction
//! Converts the integer to ID of periodic direction
static Standard_Integer ToDirectionID(const Standard_Integer theDirectionID)
{
return Abs(theDirectionID % 3);
}
protected: //! @name Protected methods performing the operation
//! Checks the validity of input data
Standard_EXPORT void CheckData();
//! Trims the shape to fit to the periodic bounds
Standard_EXPORT void Trim();
//! Makes the shape identical on opposite sides
Standard_EXPORT void MakeIdentical();
//! Splits the negative side of the shape with the geometry
//! located on the positive side copying the geometry from
//! positive side to the negative.
Standard_EXPORT void SplitNegative();
//! Splits the positive side of the shape with the geometry
//! located on the negative side of the shape.
//! Ensures that the geometries on the opposite sides will
//! be identical.
//! Associates the identical opposite sub-shapes.
Standard_EXPORT void SplitPositive();
//! Splits the shape by the given tools, copying the geometry of coinciding
//! parts from the given tools to the split shape.
//! @param theTools [in] The tools to split the shape and take the geometry
//! for coinciding parts.
//! @param theSplitShapeHistory [out] The history of shape split
//! @param theSplitToolsHistory [out] The history of tools modifications during the split
Standard_EXPORT void SplitShape(const TopTools_ListOfShape& theTools,
Handle(BRepTools_History) theSplitShapeHistory = NULL,
Handle(BRepTools_History) theSplitToolsHistory = NULL);
//! Updates the map of twins after periodic shape repetition.
//! @param theTranslationHistory [in] The history of translation of the periodic shape.
//! @param theGluingHistory [in] The history of gluing of the repeated shapes.
Standard_EXPORT void UpdateTwins(const BRepTools_History& theTranslationHistory,
const BRepTools_History& theGluingHistory);
protected: //! @name Fields
// Inputs
TopoDS_Shape myInputShape; //!< Input shape to make periodic
PeriodicityParams myPeriodicityParams; //!< Periodicity parameters
// Results
TopoDS_Shape myShape; //!< Resulting periodic shape (base for repetitions)
TopoDS_Shape myRepeatedShape; //!< Resulting shape after making repetitions of the base
Standard_Real myRepeatPeriod[3]; //!< XYZ repeat period
TopTools_DataMapOfShapeListOfShape myRepeatedTwins; //!< Map of associations of the identical sub-shapes
//! after repetition of the periodic shape
// Twins
TopTools_DataMapOfShapeListOfShape myTwins; //!< Map of associations of the identical sub-shapes
//! located on the opposite sides of the shape
// History
Handle(BRepTools_History) mySplitHistory; //!< Split history - history of shapes modification
//! after the split for making the shape periodic
Handle(BRepTools_History) myHistory; //!< Final history of shapes modifications
//! (to include the history of shape repetition)
};
#endif // _BOPAlgo_MakePeriodic_HeaderFile

View File

@@ -332,97 +332,40 @@ void BOPAlgo_MakerVolume::FillInternalShapes(const TopTools_ListOfShape& theLSR)
if (myAvoidInternalShapes) {
return;
}
//
UserBreak();
//
Standard_Integer aNbSI;
TopAbs_ShapeEnum aType;
TopAbs_State aState;
TopoDS_Iterator aItS;
BRep_Builder aBB;
// Get all non-compound shapes
TopTools_ListOfShape aLSC;
// Fence map
TopTools_MapOfShape aMFence;
TopTools_IndexedMapOfShape aMSS;
TopTools_ListOfShape aLVE, aLSC, aLSIn;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
//
// 1. Collect shapes to process: vertices, edges, wires
const TopTools_ListOfShape& anArguments = myDS->Arguments();
aIt.Initialize(anArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
}
//
aIt.Initialize(aLSC);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
aType = aS.ShapeType();
if (aType == TopAbs_WIRE) {
aItS.Initialize(aS);
for(; aItS.More(); aItS.Next()) {
const TopoDS_Shape& aE = aItS.Value();
if (aMFence.Add(aE)) {
aLVE.Append(aE);
}
TopTools_ListOfShape::Iterator itLA(myDS->Arguments());
for (; itLA.More(); itLA.Next())
BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLSC);
// Get only edges and vertices from arguments
TopTools_ListOfShape aLVE;
itLA.Initialize(aLSC);
for (; itLA.More(); itLA.Next())
{
const TopoDS_Shape& aS = itLA.Value();
TopAbs_ShapeEnum aType = aS.ShapeType();
if (aType == TopAbs_WIRE)
{
for (TopoDS_Iterator it(aS); it.More(); it.Next())
{
const TopoDS_Shape& aSS = it.Value();
if (aMFence.Add(aSS))
aLVE.Append(aSS);
}
}
else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE)
aLVE.Append(aS);
}
}
//
aIt.Initialize(theLSR);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
TopExp::MapShapes(aS, TopAbs_EDGE, aMSS);
TopExp::MapShapes(aS, TopAbs_VERTEX, aMSS);
}
//
aIt.Initialize(aLVE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
if (myImages.IsBound(aS)) {
const TopTools_ListOfShape &aLSp = myImages.Find(aS);
aIt1.Initialize(aLSp);
for (; aIt1.More(); aIt1.Next()) {
const TopoDS_Shape& aSp = aIt1.Value();
if (aMSS.Add(aSp)) {
aLSIn.Append(aSp);
}
}
}
else {
if (aMSS.Add(aS)) {
aLSIn.Append(aS);
}
}
}
//
aNbSI = aLSIn.Extent();
if (!aNbSI) {
return;
}
//
// 2. Settle internal vertices and edges into solids
aIt.Initialize(theLSR);
for (; aIt.More(); aIt.Next()) {
TopoDS_Solid aSd = *(TopoDS_Solid*)&aIt.Value();
//
aIt1.Initialize(aLSIn);
for (; aIt1.More(); ) {
TopoDS_Shape aSI = aIt1.Value();
aSI.Orientation(TopAbs_INTERNAL);
//
aState = BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
if (aState == TopAbs_IN) {
aBB.Add(aSd, aSI);
aLSIn.Remove(aIt1);
}
else {
aIt1.Next();
}
}
}
BOPAlgo_Tools::FillInternals(theLSR, aLVE, myImages, myContext);
}
//=======================================================================

View File

@@ -173,22 +173,6 @@ void BOPAlgo_PaveFiller::SetSectionAttribute
mySectionAttribute = theSecAttr;
}
//=======================================================================
//function : SetArguments
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::SetArguments(const TopTools_ListOfShape& theLS)
{
myArguments=theLS;
}
//=======================================================================
//function : Arguments
//purpose :
//=======================================================================
const TopTools_ListOfShape& BOPAlgo_PaveFiller::Arguments()const
{
return myArguments;
}
//=======================================================================
// function: Init
// purpose:
//=======================================================================
@@ -328,6 +312,8 @@ void BOPAlgo_PaveFiller::PerformInternal()
myDS->ReleasePaveBlocks();
myDS->RefineFaceInfoOn();
//
RemoveMicroEdges();
//
MakePCurves();
if (HasErrors()) {
return;

View File

@@ -125,9 +125,23 @@ public:
Standard_EXPORT const BOPDS_PIterator& Iterator();
Standard_EXPORT void SetArguments (const TopTools_ListOfShape& theLS);
Standard_EXPORT const TopTools_ListOfShape& Arguments() const;
//! Sets the arguments for operation
void SetArguments (const TopTools_ListOfShape& theLS)
{
myArguments = theLS;
}
//! Adds the argument for operation
void AddArgument(const TopoDS_Shape& theShape)
{
myArguments.Append(theShape);
}
//! Returns the list of arguments
const TopTools_ListOfShape& Arguments() const
{
return myArguments;
}
Standard_EXPORT const Handle(IntTools_Context)& Context();
@@ -548,6 +562,8 @@ protected:
Standard_EXPORT void RemoveMicroSectionEdges(BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
BOPDS_IndexedMapOfPaveBlock& theMicroPB);
//! Check all edges on the micro status and remove the positive ones
Standard_EXPORT void RemoveMicroEdges();
TopTools_ListOfShape myArguments;
BOPDS_PDS myDS;

View File

@@ -368,6 +368,9 @@ void BOPAlgo_PaveFiller::SplitPaveBlocks(const TColStd_MapOfInteger& theMEdges,
BOPDS_ListOfPaveBlock,
TColStd_MapTransientHasher> aMCBNewPB;
//
// Map of vertices to init the pave blocks for them
TColStd_MapOfInteger aMVerticesToInitPB;
TColStd_MapIteratorOfMapOfInteger aItM(theMEdges);
for (; aItM.More(); aItM.Next()) {
Standard_Integer nE = aItM.Value();
@@ -429,6 +432,10 @@ void BOPAlgo_PaveFiller::SplitPaveBlocks(const TColStd_MapOfInteger& theMEdges,
aLV.Append(nV1);
aLV.Append(nV2);
MakeSDVertices(aLV, theAddInterfs);
// Save vertices to init pave blocks
aMVerticesToInitPB.Add(nV1);
aMVerticesToInitPB.Add(nV2);
}
continue;
}
@@ -531,6 +538,11 @@ void BOPAlgo_PaveFiller::SplitPaveBlocks(const TColStd_MapOfInteger& theMEdges,
}
}
}
// Init pave blocks for vertices which have acquired SD vertex
aItM.Initialize(aMVerticesToInitPB);
for (; aItM.More(); aItM.Next())
myDS->InitPaveBlocksForVertex(aItM.Value());
}
//=======================================================================
@@ -547,4 +559,4 @@ void BOPAlgo_PaveFiller::AddIntersectionFailedWarning(const TopoDS_Shape& theS1,
BRep_Builder().Add(aWC, theS2);
// Add the warning
AddWarning(new BOPAlgo_AlertIntersectionOfPairOfShapesFailed(aWC));
}
}

View File

@@ -629,9 +629,13 @@ void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
// Get the edge
Standard_Integer nE = thePB->OriginalEdge();
if (nE < 0 && !thePB->HasEdge(nE))
return;
Standard_Integer nE = -1;
if (!thePB->HasEdge(nE))
{
nE = thePB->OriginalEdge();
if (nE < 0)
return;
}
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
// Range

View File

@@ -900,7 +900,7 @@ void BOPAlgo_PaveFiller::PostTreatFF
//
// 1 prepare arguments
TopTools_MapOfShape anAddedSD;
for (k=1; k<=aNbS; ++k) {
for (k = aNbS; k > 0; --k) {
const TopoDS_Shape& aS=theMSCPB.FindKey(k);
aLS.Append(aS);
// add vertices-candidates for SD from the map aDMNewSD,
@@ -1025,8 +1025,11 @@ void BOPAlgo_PaveFiller::PostTreatFF
if (!bIntersectionPoint) {
// save SD connection
nSx = myDS->Index(aSx);
aDMNewSD.Bind(nSx, iV);
myDS->AddShapeSD(nSx, iV);
if (nSx != iV)
{
aDMNewSD.Bind(nSx, iV);
myDS->AddShapeSD(nSx, iV);
}
}
else {
// update FF interference
@@ -1075,8 +1078,7 @@ void BOPAlgo_PaveFiller::PostTreatFF
// note we check not the edge aSx itself, but its image in aPDS
const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
aNbLPBx = aLPBx.Extent();
if (aPDS->HasPaveBlocks(nSx) &&
(aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
if (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData())) {
BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
for (; it.More(); it.Next()) {
if (it.Value() == aPB1) {
@@ -1084,6 +1086,12 @@ void BOPAlgo_PaveFiller::PostTreatFF
break;
}
}
// The edge became micro edge, check vertices for SD
TopoDS_Iterator itV(aSx);
for (; itV.More(); itV.Next())
aLS.Append(itV.Value());
continue;
}
//
@@ -2302,21 +2310,21 @@ void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_Curve& aNC,
TColStd_MapOfInteger& aMV)
{
if (!aMV.Extent()) {
if (aMV.IsEmpty())
return;
}
const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
for (; itPB.More(); itPB.Next())
{
const BOPDS_ListOfPave& aLP = itPB.Value()->ExtPaves();
BOPDS_ListIteratorOfListOfPave aItLP(aLP);
for (;aItLP.More();aItLP.Next()) {
BOPDS_Pave aPave = aItLP.Value();
Standard_Integer nV = aPave.Index();
aMV.Remove(nV);
}
const Handle(BOPDS_PaveBlock)& aPB = itPB.Value();
const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
BOPDS_ListIteratorOfListOfPave itLP(aLP);
for (; itLP.More(); itLP.Next())
aMV.Remove(itLP.Value().Index());
aMV.Remove(aPB->Pave1().Index());
aMV.Remove(aPB->Pave2().Index());
}
}
@@ -2732,42 +2740,63 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
// Find the pave which has been put at one of the ends
BOPDS_Pave aPave;
// Index of the vertex put at one of the ends
Standard_Integer nV = -1;
// Keep the opposite parameter
Standard_Real aTOp = 0.;
Standard_Boolean bFound = Standard_False;
// Keep the opposite bounding point
gp_Pnt aPOp;
Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
BOPDS_ListOfPave& aLP = aPB->ChangeExtPaves();
BOPDS_ListIteratorOfListOfPave aItLP(aLP);
for (; aItLP.More() && !bFound; aItLP.Next())
for (; aItLP.More() && (nV < 0); aItLP.Next())
{
const BOPDS_Pave& aPC = aItLP.Value();
Standard_Real aTC = aPC.Parameter();
aPave = aItLP.Value();
Standard_Real aTC = aPave.Parameter();
for (Standard_Integer j = 0; j < 2; ++j)
{
if (Abs(aTC - aT[j]) < Precision::PConfusion())
{
nV = aPC.Index();
nV = aPave.Index();
aTOp = (!j) ? aT[1] : aT[0];
bFound = Standard_True;
aPOp = (!j) ? aP[1] : aP[0];
break;
}
}
}
if (!bFound)
if (nV < 0)
// No paves on the bounds of the curve
return;
// Check if the curve is closed using the tolerance
// of found vertex
const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
const Standard_Real aTolV = BRep_Tool::Tolerance(aV);
Standard_Real aTolV = BRep_Tool::Tolerance(aV);
gp_Pnt aPV = BRep_Tool::Pnt(aV);
// Tolerance for the point on the curve
Standard_Real aTolP = Max(aNC.Tolerance(), aNC.TangentialTolerance());
aTolP += Precision::Confusion();
Standard_Real aDist = aP[0].Distance(aP[1]);
if (aDist > aTolV)
const Standard_Real aDistVP = aPV.Distance(aPOp);
if (aDistVP > aTolV + aTolP)
{
// Curve is not closed
return;
}
if (aDistVP > aTolV)
{
Standard_Integer nVn = UpdateVertex(nV, aDistVP);
if (nVn != nV)
{
aPave.SetIndex(nVn);
nV = nVn;
}
aTolV = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV)));
}
// Check if there will be valid range on the curve
Standard_Real aFirst, aLast;
@@ -2776,15 +2805,17 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
aT[1], aP[1], aTolV,
aFirst, aLast))
{
// No valid range
return;
}
// Add closing pave to the curve
BOPDS_Pave aPave;
aPave.SetIndex(nV);
aPave.SetParameter(aTOp);
aLP.Append(aPave);
BOPDS_Pave aNewPave;
aNewPave.SetIndex(nV);
aNewPave.SetParameter(aTOp);
aLP.Append(aNewPave);
}
//=======================================================================
//function : PreparePostTreatFF
//purpose :
@@ -2919,79 +2950,46 @@ void BOPAlgo_PaveFiller::UpdatePaveBlocks
bRebuild = Standard_False;
aPB->Indices(nV[0], nV[1]);
aPB->Range(aT[0], aT[1]);
Standard_Integer nE = aPB->OriginalEdge();
if (nE < 0)
// new edge
nE = aPB->Edge();
// remember the fact if the edge had different vertices before substitution
Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
TopoDS_Vertex aVE1, aVE2;
TopExp::Vertices(aE, aVE1, aVE2);
Standard_Boolean isClosedE = !aVE1.IsNull() && !aVE2.IsNull() && aVE1.IsSame(aVE2);
Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag();
//
BOPDS_Pave aPave[2] = {aPB->Pave1(), aPB->Pave2()};
for (j = 0; j < 2; ++j) {
if (aDMNewSD.IsBound(nV[j])) {
BOPDS_Pave aPave;
//
nV[j] = aDMNewSD.Find(nV[j]);
// recompute the parameter
if (!isDegEdge)
{
const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j]));
if (!isClosedE ||
BRep_Tool::Pnt(aV).Distance(BRep_Tool::Pnt(aVE1)) > BRep_Tool::Tolerance(aV) + myFuzzyValue)
{
Standard_Real aDummy, aTnew;
Standard_Integer iErr = myContext->ComputeVE(aV, aE, aTnew, aDummy, myFuzzyValue);
if (!iErr)
aT[j] = aTnew;
}
else
{
// choose the correct boundary parameter
Standard_Real f, l;
BRep_Tool::Range(aE, f, l);
aT[j] = Abs(aT[j] - f) < Abs(aT[j] - l) ? f : l;
}
}
aPave[j].SetIndex(nV[j]);
aPave.SetIndex(nV[j]);
aPave.SetParameter(aT[j]);
//
bRebuild = Standard_True;
if (!j) {
aPB->SetPave1(aPave);
}
else {
aPB->SetPave2(aPave);
}
}
}
//
if (bRebuild) {
if (aT[0] < aT[1])
{
// It seems the parameters have been recomputed successfully
aPave[0].SetParameter(aT[0]);
aPave[1].SetParameter(aT[1]);
Standard_Integer nE = aPB->Edge();
// Check if the Pave Block has the edge set
if (nE < 0) {
// untouched edge
nE = aPB->OriginalEdge();
}
aPB->SetPave1(aPave[0]);
aPB->SetPave2(aPave[1]);
Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag();
if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
// now edge has the same vertex on both ends;
// check if it is not a regular closed curve.
FillShrunkData(aPB);
if (!aPB->HasShrunkData())
{
Standard_Integer nEMicro = aPB->Edge();
if (nEMicro < 0)
nEMicro = aPB->OriginalEdge();
// micro edge, so mark it for removal
aMicroEdges.Add(nEMicro);
aMicroEdges.Add(nE);
continue;
}
}
aPB->Range(aT[0], aT[1]);
nSp = SplitEdge(nE, nV[0], aT[0], nV[1], aT[1]);
if (bCB)
aCB->SetEdge(nSp);
@@ -3029,41 +3027,12 @@ void BOPAlgo_PaveFiller::RemovePaveBlocks(const TColStd_MapOfInteger theEdges)
}
}
// 2. from Face Info and section curves
// 2. from section curves
TColStd_MapOfInteger aMPassed;
BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
Standard_Integer aNbFF = aFFs.Length(), j;
for (i = 0; i < aNbFF; ++i) {
BOPDS_InterfFF& aFF = aFFs(i);
Standard_Integer nF1, nF2;
aFF.Indices(nF1, nF2);
//
// rebuild pave block maps of face info
for (j = 0; j < 2; j++) {
Standard_Integer nF = (j == 0 ? nF1 : nF2);
if (!aMPassed.Add(nF))
continue;
BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
&aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
for (Standard_Integer k = 0; k < 3; k++) {
Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
for (m = 1; m <= aNbPB; ++m) {
const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
if (theEdges.Contains(aPB->Edge()))
break;
}
if (m <= aNbPB) {
BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
aIMPB[k]->Clear();
for (m = 1; m <= aNbPB; ++m) {
const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
if (!theEdges.Contains(aPB->Edge()))
aIMPB[k]->Add(aPB);
}
}
}
}
// remove from Section pave blocks
BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
Standard_Integer aNbC = aVNC.Length();
@@ -3080,7 +3049,44 @@ void BOPAlgo_PaveFiller::RemovePaveBlocks(const TColStd_MapOfInteger theEdges)
}
}
}
// 3. From Face Info
for (i = 0; i < myDS->NbSourceShapes(); ++i)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_FACE)
continue;
if (!aSI.HasReference())
continue;
BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
&aFI.ChangePaveBlocksOn(),
&aFI.ChangePaveBlocksSc() };
for (Standard_Integer k = 0; k < 3; k++)
{
Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
for (m = 1; m <= aNbPB; ++m)
{
const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
if (theEdges.Contains(aPB->Edge()))
break;
}
if (m <= aNbPB)
{
BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
aIMPB[k]->Clear();
for (m = 1; m <= aNbPB; ++m)
{
const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
if (!theEdges.Contains(aPB->Edge()))
aIMPB[k]->Add(aPB);
}
}
}
}
}
//=======================================================================
//function : ToleranceFF
//purpose : Computes the TolFF according to the tolerance value and
@@ -3507,3 +3513,49 @@ void BOPAlgo_PaveFiller::RemoveMicroSectionEdges
if (aSEPBMap.Extent() != theMSCPB.Extent())
theMSCPB = aSEPBMap;
}
//=======================================================================
//function : RemoveMicroEdges
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::RemoveMicroEdges()
{
// Fence map
BOPDS_MapOfPaveBlock aMPBFence;
// Resulting map of micro edges
TColStd_MapOfInteger aMicroEdges;
// Check all pave blocks from the pool to find the micro edges
BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
Standard_Integer aNbPBP = aPBP.Length();
for (Standard_Integer i = 0; i < aNbPBP; ++i)
{
BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
if (aLPB.Extent() < 2)
// No splits
continue;
if (myDS->ShapeInfo(aLPB.First()->OriginalEdge()).HasFlag())
continue;
BOPDS_ListOfPaveBlock::Iterator it(aLPB);
for (; it.More(); it.Next())
{
const Handle(BOPDS_PaveBlock)& aPB = it.Value();
Handle(BOPDS_PaveBlock) aPBR = myDS->RealPaveBlock(aPB);
if (aMPBFence.Add(aPBR))
{
Standard_Integer nV1, nV2;
aPBR->Indices(nV1, nV2);
if (nV1 == nV2)
{
// Check if it has the valid range
FillShrunkData(aPBR);
if (!aPBR->HasShrunkData())
aMicroEdges.Add(aPBR->Edge());
}
}
}
}
RemovePaveBlocks(aMicroEdges);
}

View File

@@ -17,6 +17,8 @@
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <TopoDS_Iterator.hxx>
//=======================================================================
//function :
//purpose :
@@ -98,3 +100,31 @@ void BOPAlgo_Splitter::Perform()
myEntryPoint = 1;
PerformInternal(*pPF);
}
//=======================================================================
//function : BuildResult
//purpose :
//=======================================================================
void BOPAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
{
BOPAlgo_Builder::BuildResult(theType);
if (theType == TopAbs_COMPOUND)
{
// The method is called for the last time for this operation.
// If there is only one argument shape and it has been modified into
// a single shape, or has not been modified at all, the result shape
// has to be overwritten to avoid the unnecessary enclosure into compound.
if (myArguments.Extent() == 1)
{
TopoDS_Iterator it(myShape);
if (it.More())
{
const TopoDS_Shape& aSFirst = it.Value();
it.Next();
if (!it.More())
myShape = aSFirst;
}
}
}
}

View File

@@ -66,6 +66,12 @@ protected:
//! Checks the input data
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
//! Adds images of the argument shapes into result.
//! When called the for the last time (for compound) it rebuilds the result
//! shape to avoid multiple enclosure into compounds.
Standard_EXPORT virtual void BuildResult(const TopAbs_ShapeEnum theType) Standard_OVERRIDE;
};
#endif // _BOPAlgo_Splitter_HeaderFile

View File

@@ -1643,3 +1643,148 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces,
theInParts.Add(aS, aLFIn);
}
}
//=======================================================================
//function : FillInternals
//purpose :
//=======================================================================
void BOPAlgo_Tools::FillInternals(const TopTools_ListOfShape& theSolids,
const TopTools_ListOfShape& theParts,
const TopTools_DataMapOfShapeListOfShape& theImages,
const Handle(IntTools_Context)& theContext)
{
if (theSolids.IsEmpty() || theParts.IsEmpty())
return;
// Map the solids to avoid classification of the own shapes of the solids
TopTools_IndexedMapOfShape aMSSolids;
TopTools_ListOfShape::Iterator itLS(theSolids);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aSolid = itLS.Value();
if (aSolid.ShapeType() == TopAbs_SOLID)
{
TopExp::MapShapes(aSolid, TopAbs_VERTEX, aMSSolids);
TopExp::MapShapes(aSolid, TopAbs_EDGE, aMSSolids);
TopExp::MapShapes(aSolid, TopAbs_FACE, aMSSolids);
}
}
// Extract BRep elements from the given parts and
// check them for possible splits
TopTools_ListOfShape aLPartsInput = theParts, aLParts;
TopTools_ListOfShape::Iterator itLP(aLPartsInput);
for (; itLP.More(); itLP.Next())
{
const TopoDS_Shape& aPart = itLP.Value();
switch (aPart.ShapeType())
{
case TopAbs_VERTEX:
case TopAbs_EDGE:
case TopAbs_FACE:
{
const TopTools_ListOfShape* pIm = theImages.Seek(aPart);
if (pIm)
{
TopTools_ListOfShape::Iterator itIm(*pIm);
for (; itIm.More(); itIm.Next())
{
const TopoDS_Shape& aPartIm = itIm.Value();
if (!aMSSolids.Contains(aPartIm))
aLParts.Append(aPartIm);
}
}
else if (!aMSSolids.Contains(aPart))
aLParts.Append(aPart);
break;
}
default:
{
for (TopoDS_Iterator it(aPart); it.More(); it.Next())
aLPartsInput.Append(it.Value());
break;
}
}
}
// Classify the given parts relatively solids.
// Add edges and vertices classified as IN into solids instantly,
// and collect faces classified as IN into a list for further shell creation
TopTools_DataMapOfShapeListOfShape anINFaces;
itLS.Initialize(theSolids);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aSolid = itLS.Value();
if (aSolid.ShapeType() != TopAbs_SOLID)
continue;
TopoDS_Solid aSd = *(TopoDS_Solid*)&aSolid;
itLP.Initialize(aLParts);
for (; itLP.More();)
{
TopoDS_Shape aPart = itLP.Value();
TopAbs_State aState =
BOPTools_AlgoTools::ComputeStateByOnePoint(aPart, aSd, Precision::Confusion(), theContext);
if (aState == TopAbs_IN)
{
if (aPart.ShapeType() == TopAbs_FACE)
{
TopTools_ListOfShape *pFaces = anINFaces.ChangeSeek(aSd);
if (!pFaces)
pFaces = anINFaces.Bound(aSd, TopTools_ListOfShape());
pFaces->Append(aPart);
}
else
{
aPart.Orientation(TopAbs_INTERNAL);
BRep_Builder().Add(aSd, aPart);
}
aLParts.Remove(itLP);
}
else
itLP.Next();
}
}
// Make shells from faces and put them into solids
TopTools_DataMapOfShapeListOfShape::Iterator itM(anINFaces);
for (; itM.More(); itM.Next())
{
TopoDS_Solid aSd = *(TopoDS_Solid*)&itM.Key();
const TopTools_ListOfShape& aFaces = itM.Value();
TopoDS_Compound aCF;
BRep_Builder().MakeCompound(aCF);
TopTools_ListOfShape::Iterator itLF(aFaces);
for (; itLF.More(); itLF.Next())
BRep_Builder().Add(aCF, itLF.Value());
// Build blocks from the faces
TopTools_ListOfShape aLCB;
BOPTools_AlgoTools::MakeConnexityBlocks(aCF, TopAbs_EDGE, TopAbs_FACE, aLCB);
// Build shell from each block
TopTools_ListOfShape::Iterator itCB(aLCB);
for (; itCB.More(); itCB.Next())
{
const TopoDS_Shape& aCB = itCB.Value();
TopoDS_Shell aShell;
BRep_Builder().MakeShell(aShell);
// Add faces of the block to the shell
TopExp_Explorer expF(aCB, TopAbs_FACE);
for (; expF.More(); expF.Next())
{
TopoDS_Face aFInt = TopoDS::Face(expF.Current());
aFInt.Orientation(TopAbs_INTERNAL);
BRep_Builder().Add(aShell, aFInt);
}
BRep_Builder().Add(aSd, aShell);
}
}
}

View File

@@ -194,6 +194,18 @@ public:
const TopTools_DataMapOfShapeBox& theShapeBoxMap = TopTools_DataMapOfShapeBox(),
const TopTools_DataMapOfShapeListOfShape& theSolidsIF = TopTools_DataMapOfShapeListOfShape());
//! Classifies the given parts relatively the given solids and
//! fills the solids with the parts classified as INTERNAL.
//!
//! @param theSolids - The solids to put internals to
//! @param theParts - The parts to classify relatively solids
//! @param theImages - Possible images of the parts that has to be classified
//! @param theContext - Cashed geometrical tools to speed-up classifications
Standard_EXPORT static void FillInternals(const TopTools_ListOfShape& theSolids,
const TopTools_ListOfShape& theParts,
const TopTools_DataMapOfShapeListOfShape& theImages,
const Handle(IntTools_Context)& theContext);
};
#endif // _BOPAlgo_Tools_HeaderFile

View File

@@ -27,6 +27,10 @@ BOPAlgo_CheckResult.cxx
BOPAlgo_CheckResult.hxx
BOPAlgo_CheckStatus.hxx
BOPAlgo_ListOfCheckResult.hxx
BOPAlgo_MakeConnected.cxx
BOPAlgo_MakeConnected.hxx
BOPAlgo_MakePeriodic.cxx
BOPAlgo_MakePeriodic.hxx
BOPAlgo_MakerVolume.cxx
BOPAlgo_MakerVolume.hxx
BOPAlgo_MakerVolume.lxx

View File

@@ -57,6 +57,8 @@ void BOPTest::AllCommands(Draw_Interpretor& theCommands)
BOPTest::CellsCommands (theCommands);
BOPTest::UtilityCommands (theCommands);
BOPTest::RemoveFeaturesCommands(theCommands);
BOPTest::PeriodicityCommands(theCommands);
BOPTest::MkConnectedCommands(theCommands);
}
//=======================================================================
//function : Factory
@@ -90,6 +92,7 @@ void BOPTest::ReportAlerts(const Handle(Message_Report)& theReport)
{
// first report warnings, then errors
Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
TCollection_ExtendedString aMsgType[2] = { "Warning: ", "Error: " };
for (int iGravity = 0; iGravity < 2; iGravity++)
{
// report shapes for the same type of alert together
@@ -104,7 +107,7 @@ void BOPTest::ReportAlerts(const Handle(Message_Report)& theReport)
// get alert message
Message_Msg aMsg (aIt.Value()->GetMessageKey());
TCollection_ExtendedString aText = aMsg.Get();
TCollection_ExtendedString aText = aMsgType[iGravity] + aMsg.Get();
// collect all shapes if any attached to this alert
if (BOPTest_Objects::DrawWarnShapes())

View File

@@ -60,6 +60,10 @@ public:
Standard_EXPORT static void RemoveFeaturesCommands (Draw_Interpretor& aDI);
Standard_EXPORT static void PeriodicityCommands (Draw_Interpretor& aDI);
Standard_EXPORT static void MkConnectedCommands (Draw_Interpretor& aDI);
//! Prints errors and warnings if any and draws attached shapes
//! if flag BOPTest_Objects::DrawWarnShapes() is set
Standard_EXPORT static void ReportAlerts (const Handle(Message_Report)& theReport);

View File

@@ -0,0 +1,413 @@
// Created on: 04/02/2018
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPTest.hxx>
#include <BOPAlgo_MakeConnected.hxx>
#include <BOPTest_DrawableShape.hxx>
#include <BOPTest_Objects.hxx>
#include <BRep_Builder.hxx>
#include <BRepTest_Objects.hxx>
#include <DBRep.hxx>
#include <Draw.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
static Standard_Integer MakeConnected(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer MakePeriodic(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer MaterialsOn(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer RepeatShape(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer GetTwins(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer ClearRepetitions(Draw_Interpretor&, Standard_Integer, const char**);
namespace
{
static BOPAlgo_MakeConnected TheMakeConnectedTool;
}
//=======================================================================
//function : MkConnectedCommands
//purpose :
//=======================================================================
void BOPTest::MkConnectedCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean done = Standard_False;
if (done) return;
done = Standard_True;
// Chapter's name
const char* group = "BOPTest commands";
// Commands
theCommands.Add("makeconnected", "makeconnected result shape1 shape2 ...\n"
"\t\tMake the given shapes connected (glued).",
__FILE__, MakeConnected, group);
theCommands.Add("cmakeperiodic", "cmakeperiodic result [-x/y/z period [-trim first]]\n"
"\t\tMake the connected shape periodic in the required directions.\n"
"\t\tresult - resulting periodic shape;\n"
"\t\t-x/y/z period - option to make the shape periodic in X, Y or Z\n "
"\t\t direction with the given period;\n"
"\t\t-trim first - option to trim the shape to fit the required period,\n"
"\t\t starting the period in first.",
__FILE__, MakePeriodic, group);
theCommands.Add("cmaterialson", "cmaterialson result +/- shape\n"
"\t\tReturns the original shapes located on the required side of a shape:\n"
"\t\t'+' - on a positive side of a shape (containing the shape with orientation FORWARD)\n"
"\t\t'-' - on a negative side of a shape (containing the shape with orientation REVERSED).",
__FILE__, MaterialsOn, group);
theCommands.Add("crepeatshape", "crepeatshape result -x/y/z times\n"
"\t\tRepeats the periodic connected shape in periodic directions required number of times.\n"
"\t\tresult - resulting shape;\n"
"\t\t-x/y/z times - direction for repetition and number of repetitions.",
__FILE__, RepeatShape, group);
theCommands.Add("cperiodictwins", "cperiodictwins twins shape\n"
"\t\tReturns the twins for the shape located on the opposite side of the periodic shape.",
__FILE__, GetTwins, group);
theCommands.Add("cclearrepetitions", "cclearrepetitions [result]\n"
"\t\tClears all previous repetitions of the periodic shape.",
__FILE__, ClearRepetitions, group);
}
//=======================================================================
//function : MakeConnected
//purpose :
//=======================================================================
Standard_Integer MakeConnected(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc < 3)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
TheMakeConnectedTool.Clear();
for (Standard_Integer i = 2; i < theArgc; ++i)
{
TopoDS_Shape aS = DBRep::Get(theArgv[i]);
if (aS.IsNull())
{
theDI << "Error: " << theArgv[i] << " is a null shape. Skip it.\n";
continue;
}
TheMakeConnectedTool.AddArgument(aS);
}
TheMakeConnectedTool.SetRunParallel(BOPTest_Objects::RunParallel());
TheMakeConnectedTool.Perform();
// Print Error/Warning messages
BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
// Set the history of the operation in session
BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
if (TheMakeConnectedTool.HasErrors())
return 0;
// Draw the result shape
const TopoDS_Shape& aResult = TheMakeConnectedTool.Shape();
DBRep::Set(theArgv[1], aResult);
return 0;
}
//=======================================================================
//function : MakePeriodic
//purpose :
//=======================================================================
Standard_Integer MakePeriodic(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc < 4)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
if (TheMakeConnectedTool.Shape().IsNull() || TheMakeConnectedTool.HasErrors())
{
theDI << "Make the shapes connected first.\n";
return 1;
}
BOPAlgo_MakePeriodic::PeriodicityParams aParams;
for (Standard_Integer i = 2; i < theArgc;)
{
Standard_Integer aDirID = -1;
if (!strcasecmp(theArgv[i], "-x"))
aDirID = 0;
else if (!strcasecmp(theArgv[i], "-y"))
aDirID = 1;
else if (!strcasecmp(theArgv[i], "-z"))
aDirID = 2;
else
{
theDI << theArgv[i] << " - Invalid key\n";
return 1;
}
char cDirName[2];
sprintf(cDirName, "%c", theArgv[i][1]);
Standard_Real aPeriod = 0;
if (theArgc > i + 1)
aPeriod = Draw::Atof(theArgv[++i]);
if (aPeriod <= Precision::Confusion())
{
theDI << "Period for " << cDirName << " direction is not set\n";
return 1;
}
aParams.myPeriodic[aDirID] = Standard_True;
aParams.myPeriod[aDirID] = aPeriod;
++i;
if (theArgc > i + 1)
{
// Check if trimming is necessary
if (!strcmp(theArgv[i], "-trim"))
{
if (theArgc == (i + 1))
{
theDI << "Trim bounds for " << cDirName << " direction are not set\n";
return 1;
}
Standard_Real aFirst = Draw::Atof(theArgv[++i]);
aParams.myIsTrimmed[aDirID] = Standard_False;
aParams.myPeriodFirst[aDirID] = aFirst;
++i;
}
}
}
TheMakeConnectedTool.MakePeriodic(aParams);
// Print Error/Warning messages
BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
// Set the history of the operation in session
BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
if (TheMakeConnectedTool.HasErrors())
return 0;
// Draw the result shape
const TopoDS_Shape& aResult = TheMakeConnectedTool.PeriodicShape();
DBRep::Set(theArgv[1], aResult);
return 0;
}
//=======================================================================
//function : RepeatShape
//purpose :
//=======================================================================
Standard_Integer RepeatShape(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc < 4)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
if (TheMakeConnectedTool.PeriodicityTool().HasErrors())
{
theDI << "The shapes have not been made periodic yet.\n";
return 1;
}
for (Standard_Integer i = 2; i < theArgc; ++i)
{
Standard_Integer aDirID = -1;
if (!strcasecmp(theArgv[i], "-x"))
aDirID = 0;
else if (!strcasecmp(theArgv[i], "-y"))
aDirID = 1;
else if (!strcasecmp(theArgv[i], "-z"))
aDirID = 2;
else
{
theDI << theArgv[i] << " - Invalid key\n";
return 1;
}
char cDirName[2];
sprintf(cDirName, "%c", theArgv[i][1]);
Standard_Integer aTimes = 0;
if (theArgc > i + 1)
aTimes = Draw::Atoi(theArgv[++i]);
if (aTimes == 0)
{
theDI << "Number of repetitions for " << cDirName << " direction is not set\n";
return 1;
}
TheMakeConnectedTool.RepeatShape(aDirID, aTimes);
}
// Print Error/Warning messages
BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
// Set the history of the operation in session
BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
if (TheMakeConnectedTool.HasErrors())
return 0;
// Draw the result shape
const TopoDS_Shape& aResult = TheMakeConnectedTool.PeriodicShape();
DBRep::Set(theArgv[1], aResult);
return 0;
}
//=======================================================================
//function : MaterialsOn
//purpose :
//=======================================================================
Standard_Integer MaterialsOn(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc != 4)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
// Get the shape to get materials
TopoDS_Shape aShape = DBRep::Get(theArgv[3]);
if (aShape.IsNull())
{
theDI << "Error: " << theArgv[3] << " is a null shape.\n";
return 1;
}
// Get the sign of a shape
Standard_Boolean bPositive;
if (!strcmp("+", theArgv[2]))
bPositive = Standard_True;
else if (!strcmp("-", theArgv[2]))
bPositive = Standard_False;
else
{
theDI << theArgv[2] << " - invalid key.\n";
return 1;
}
const TopTools_ListOfShape& aLS = bPositive ?
TheMakeConnectedTool.MaterialsOnPositiveSide(aShape) :
TheMakeConnectedTool.MaterialsOnNegativeSide(aShape);
TopoDS_Shape aResult;
if (aLS.IsEmpty())
theDI << "No materials on this side.\n";
else if (aLS.Extent() == 1)
aResult = aLS.First();
else
{
BRep_Builder().MakeCompound(TopoDS::Compound(aResult));
for (TopTools_ListIteratorOfListOfShape it(aLS); it.More(); it.Next())
BRep_Builder().Add(aResult, it.Value());
}
DBRep::Set(theArgv[1], aResult);
return 0;
}
//=======================================================================
//function : GetTwin
//purpose :
//=======================================================================
Standard_Integer GetTwins(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc != 3)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
// Get the shape to find twins
TopoDS_Shape aShape = DBRep::Get(theArgv[2]);
if (aShape.IsNull())
{
theDI << "Error: " << theArgv[2] << " is a null shape.\n";
return 1;
}
const TopTools_ListOfShape& aTwins = TheMakeConnectedTool.PeriodicityTool().GetTwins(aShape);
TopoDS_Shape aCTwins;
if (aTwins.IsEmpty())
theDI << "No twins for the shape.\n";
else if (aTwins.Extent() == 1)
aCTwins = aTwins.First();
else
{
BRep_Builder().MakeCompound(TopoDS::Compound(aCTwins));
for (TopTools_ListIteratorOfListOfShape it(aTwins); it.More(); it.Next())
BRep_Builder().Add(aCTwins, it.Value());
}
DBRep::Set(theArgv[1], aCTwins);
return 0;
}
//=======================================================================
//function : ClearRepetitions
//purpose :
//=======================================================================
Standard_Integer ClearRepetitions(Draw_Interpretor&,
Standard_Integer theArgc,
const char **theArgv)
{
// Clear all previous repetitions
TheMakeConnectedTool.ClearRepetitions();
// Set the history of the operation in session
BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
if (theArgc > 1)
DBRep::Set(theArgv[1], TheMakeConnectedTool.PeriodicShape());
return 0;
}

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