mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-24 13:50:49 +03:00
Compare commits
45 Commits
CR33095_AL
...
CR0_IntSeg
Author | SHA1 | Date | |
---|---|---|---|
|
cb2e41f927 | ||
|
6466cc9eb1 | ||
|
f7fc0c03be | ||
|
67312b7991 | ||
|
f4a7308f61 | ||
|
53d770b3a2 | ||
|
7ed6e985e2 | ||
|
da6b95a075 | ||
|
565baee64b | ||
|
36e28f96f6 | ||
|
215dd33149 | ||
|
5646c90e87 | ||
|
97e0059b05 | ||
|
8445efca81 | ||
|
a6a66c3a21 | ||
|
cc99be369e | ||
|
1a5007a920 | ||
|
3818aacaa5 | ||
|
e1d039d56d | ||
|
a4815d5509 | ||
|
ba00aab7a0 | ||
|
aaf8d6a98d | ||
|
b008226203 | ||
|
eff3eff916 | ||
|
bf327822d6 | ||
|
63da0df9c2 | ||
|
13a44c4b7f | ||
|
f04de1335c | ||
|
c08fd12706 | ||
|
d7992a77f6 | ||
|
8c787b5fa9 | ||
|
44fafc477f | ||
|
780fbc2897 | ||
|
620a6baa59 | ||
|
89073268fd | ||
|
6ed44b1ca9 | ||
|
746cb7c328 | ||
|
8ba3d978db | ||
|
c275673dbf | ||
|
9e3045dae1 | ||
|
c2bcd98369 | ||
|
683b72c3c1 | ||
|
3358ed643b | ||
|
2724a0b3cc | ||
|
0deeff45a0 |
@@ -108,6 +108,7 @@ else()
|
||||
elseif (ANDROID)
|
||||
set (CSF_ThreadLibs "c")
|
||||
set (CSF_OpenGlLibs "EGL GLESv2")
|
||||
set (CSF_androidlog "log")
|
||||
elseif (UNIX)
|
||||
set (CSF_ThreadLibs "pthread rt stdc++")
|
||||
if (USE_GLES2)
|
||||
|
@@ -12,18 +12,12 @@ macro (OCCT_CHECK_AND_UNSET VARNAME)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (OCCT_CHECK_AND_UNSET_GROUP VARNAME)
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_DIR")
|
||||
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_INCLUDE_DIR")
|
||||
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY")
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_LIBRARY_DIR")
|
||||
|
||||
if (WIN32)
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL")
|
||||
OCCT_CHECK_AND_UNSET ("${VARNAME}_DLL_DIR")
|
||||
endif()
|
||||
macro (OCCT_CHECK_AND_UNSET_GROUP GROUPNAME)
|
||||
get_cmake_property(VARS VARIABLES)
|
||||
string (REGEX MATCHALL "(^|;)${GROUPNAME}[A-Za-z0-9_]*" GROUPNAME_VARS "${VARS}")
|
||||
foreach(GROUPNAME_VAR ${GROUPNAME_VARS})
|
||||
OCCT_CHECK_AND_UNSET(${GROUPNAME_VAR})
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro (OCCT_CHECK_AND_UNSET_INSTALL_DIR_SUBDIRS)
|
||||
|
@@ -1419,6 +1419,9 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
|
||||
set aFrmsMap(CSF_TclTkLibs) "Tk"
|
||||
set aLibsMap(CSF_TclTkLibs) ""
|
||||
set aLibsMap(CSF_QT) "QtCore QtGui"
|
||||
} elseif { "$theOS" == "android" } {
|
||||
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
||||
set aLibsMap(CSF_androidlog) "log"
|
||||
} else {
|
||||
set aLibsMap(CSF_fontconfig) "fontconfig"
|
||||
if { "$theOS" == "qnx" } {
|
||||
|
@@ -14,6 +14,7 @@ overview/overview.md
|
||||
../samples/qt/AndroidQt/ReadMe.md
|
||||
../samples/java/jniviewer/ReadMe.md
|
||||
../samples/ios/UIKitSample/ReadMe.md
|
||||
../samples/webgl/ReadMe.md
|
||||
|
||||
tutorial/tutorial.md
|
||||
|
||||
|
@@ -1857,3 +1857,34 @@ The following API changes have been made:
|
||||
@subsection upgrade_740_stdnamespace Standard_Stream.hxx no more has "using std::" statements
|
||||
*Standard_Stream.hxx* header, commonly included by other OCCT header files, does no more add entities from *std namespace* related to streams (like *std::cout*, *std::istream* and others) into global namespace.
|
||||
The application code relying on this matter should be updated to either specify std namespace explicitly (like std::cout) or add "using std::" statements locally.
|
||||
|
||||
@section upgrade_occt750 Upgrade to OCCT 7.5.0
|
||||
|
||||
@subsection upgrade_750_srgb_color RGB color definition
|
||||
|
||||
OCCT 3D Viewer has been improved to properly perform lighting using in linear RGB color space and then convert result into non-linear gamma-shifted sRGB color space before displaying on display.
|
||||
This change affects texture mapping, material definition and color definition.
|
||||
|
||||
Previously *Quantity_Color* definition was provided with unspecified RGB color space.
|
||||
In practice, mixed color spaces have been actually used, with non-linear sRGB prevailing in general.
|
||||
Since OCCT 7.5.0, *Quantity_Color* now specifies that components are defined in linear RGB color space.
|
||||
|
||||
This change affects following parts:
|
||||
* Standard colors defined by *Quantity_NameOfColor* enumeration have been converted into linear RGB values within Quantity_Color construction.
|
||||
* Application may use new enumeration value *Quantity_TOC_sRGB* for passing/fetching colors in sRGB color space,
|
||||
which can be useful for interoperation with color picking widgets (returning 8-bit integer values within [0..255] range)
|
||||
or for porting colors constants within old application code without manual conversion.
|
||||
* *Graphic3d_MaterialAspect* color components are now expected in linear RGB color space,
|
||||
and standard OCCT materials within *Graphic3d_NameOfMaterial* enumeration have been updated accordingly.
|
||||
* Texture mapping now handles new *Graphic3d_TextureRoot::IsColorMap()* for interpreting content in linear RGB or sRGB color space.
|
||||
It is responsibility of user specifying this flag correctly. The flag value is TRUE by default.
|
||||
* Method *Image_PixMap::PixelColor()* has been extended with a new Boolean flag for performing linearization of non-linear sRGB.
|
||||
This flag is FALSE by default; application should consider passing TRUE instead for further handling *Quantity_Color* properly as linear RGB values.
|
||||
|
||||
@subsection upgrade_750_aspectwindow Aspect_Window interface change
|
||||
|
||||
Unexpected const-ness of Aspect_Window::DoResize() method has been removed, so that application classes implementing this interface should be updated accordingly.
|
||||
|
||||
@subsection upgrade_750_rename Renaming of types
|
||||
|
||||
Enumeration BRepOffset_Type is renamed to ChFiDS_TypeOfConcavity.
|
||||
|
BIN
dox/overview/images/sample_webgl.png
Normal file
BIN
dox/overview/images/sample_webgl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
@@ -153,6 +153,9 @@ on this tool.
|
||||
**RapidJSON** is an Open Source JSON parser and generator for C++.
|
||||
RapidJSON is optionally used by OCCT for reading glTF files (https://rapidjson.org/).
|
||||
|
||||
**DejaVu** fonts are a font family based on the Vera Fonts under a permissive license (MIT-like, https://dejavu-fonts.github.io/License.html).
|
||||
DejaVu Sans (basic Latin sub-set) is used by OCCT as fallback font when no system font is available.
|
||||
|
||||
Adobe Systems, Inc. provides **Adobe Reader**, which can be used to view files in Portable Document Format (PDF).
|
||||
|
||||
@section OCCT_OVW_SECTION_3 Documentation
|
||||
@@ -211,6 +214,7 @@ for which OCCT is certified to work.
|
||||
| Linux | GNU gcc 4.3+ <br> LLVM CLang 3.6+ |
|
||||
| OS X / macOS | XCode 6 or newer |
|
||||
| Android | NDK r10, GNU gcc 4.8 or newer |
|
||||
| Web | Emscripten SDK 1.39 or newer (CLang) |
|
||||
|
||||
1) VC++ 141 64-bit is used for regular testing and for building binary package of official release of OCCT on Windows.
|
||||
|
||||
@@ -569,3 +573,11 @@ There is a sample demonstrating usage of OCCT on iOS with Apple UIKit framework.
|
||||
@figure{/overview/images/sample_ios_uikit.png}
|
||||
|
||||
See \subpage occt_samples_ios_uikit "iOS sample Readme" for details.
|
||||
|
||||
@subsubsection OCCT_OVW_SECTION_7_3_6 Web
|
||||
|
||||
WebGL Viewer sample demonstrating usage of OCCT 3D Viewer in Web browser with Emscripten SDK can be found in `samples/webgl`.
|
||||
|
||||
@figure{/overview/images/sample_webgl.png}
|
||||
|
||||
See \subpage occt_samples_webgl "WebGL sample Readme" for details.
|
||||
|
@@ -35,13 +35,49 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Convert GLFW mouse button into Aspect_VKeyMouse.
|
||||
static Aspect_VKeyMouse mouseButtonFromGlfw (int theButton)
|
||||
{
|
||||
switch (theButton)
|
||||
{
|
||||
case GLFW_MOUSE_BUTTON_LEFT: return Aspect_VKeyMouse_LeftButton;
|
||||
case GLFW_MOUSE_BUTTON_RIGHT: return Aspect_VKeyMouse_RightButton;
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE: return Aspect_VKeyMouse_MiddleButton;
|
||||
}
|
||||
return Aspect_VKeyMouse_NONE;
|
||||
}
|
||||
|
||||
//! Convert GLFW key modifiers into Aspect_VKeyFlags.
|
||||
static Aspect_VKeyFlags keyFlagsFromGlfw (int theFlags)
|
||||
{
|
||||
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
||||
if ((theFlags & GLFW_MOD_SHIFT) != 0)
|
||||
{
|
||||
aFlags |= Aspect_VKeyFlags_SHIFT;
|
||||
}
|
||||
if ((theFlags & GLFW_MOD_CONTROL) != 0)
|
||||
{
|
||||
aFlags |= Aspect_VKeyFlags_CTRL;
|
||||
}
|
||||
if ((theFlags & GLFW_MOD_ALT) != 0)
|
||||
{
|
||||
aFlags |= Aspect_VKeyFlags_ALT;
|
||||
}
|
||||
if ((theFlags & GLFW_MOD_SUPER) != 0)
|
||||
{
|
||||
aFlags |= Aspect_VKeyFlags_META;
|
||||
}
|
||||
return aFlags;
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : GlfwOcctView
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
GlfwOcctView::GlfwOcctView()
|
||||
: myCurAction3d (CurAction3d_Nothing),
|
||||
myToRedraw (true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -193,15 +229,7 @@ void GlfwOcctView::mainloop()
|
||||
glfwWaitEvents();
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
if (myView->IsInvalidated())
|
||||
{
|
||||
myView->Redraw();
|
||||
}
|
||||
else if (myToRedraw)
|
||||
{
|
||||
myView->RedrawImmediate();
|
||||
}
|
||||
myToRedraw = false;
|
||||
FlushViewEvents (myContext, myView, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,7 +265,6 @@ void GlfwOcctView::onResize (int theWidth, int theHeight)
|
||||
myView->MustBeResized();
|
||||
myView->Invalidate();
|
||||
myView->Redraw();
|
||||
//myToRedraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,13 +274,10 @@ void GlfwOcctView::onResize (int theWidth, int theHeight)
|
||||
// ================================================================
|
||||
void GlfwOcctView::onMouseScroll (double theOffsetX, double theOffsetY)
|
||||
{
|
||||
if (myView.IsNull()) { return; }
|
||||
|
||||
const Graphic3d_Vec2i aPos = myOcctWindow->CursorPosition();
|
||||
myView->StartZoomAtPoint (aPos.x(), aPos.y());
|
||||
myView->ZoomAtPoint (0, 0, int(theOffsetY * 4.0), int(theOffsetY * 4.0));
|
||||
myView->Invalidate();
|
||||
myToRedraw = true;
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
UpdateZoom (Aspect_ScrollDelta (myOcctWindow->CursorPosition(), int(theOffsetY * 8.0)));
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
@@ -265,27 +289,13 @@ void GlfwOcctView::onMouseButton (int theButton, int theAction, int theMods)
|
||||
if (myView.IsNull()) { return; }
|
||||
|
||||
const Graphic3d_Vec2i aPos = myOcctWindow->CursorPosition();
|
||||
if (theAction != GLFW_PRESS)
|
||||
if (theAction == GLFW_PRESS)
|
||||
{
|
||||
myCurAction3d = CurAction3d_Nothing;
|
||||
return;
|
||||
PressMouseButton (aPos, mouseButtonFromGlfw (theButton), keyFlagsFromGlfw (theMods), false);
|
||||
}
|
||||
|
||||
myMouseMin = aPos;
|
||||
myMouseMax = aPos;
|
||||
switch (theButton)
|
||||
else
|
||||
{
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
{
|
||||
myCurAction3d = CurAction3d_DynamicRoation;
|
||||
myView->StartRotation (aPos.x(), aPos.y());
|
||||
break;
|
||||
}
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
{
|
||||
myCurAction3d = CurAction3d_DynamicPanning;
|
||||
break;
|
||||
}
|
||||
ReleaseMouseButton (aPos, mouseButtonFromGlfw (theButton), keyFlagsFromGlfw (theMods), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,30 +305,9 @@ void GlfwOcctView::onMouseButton (int theButton, int theAction, int theMods)
|
||||
// ================================================================
|
||||
void GlfwOcctView::onMouseMove (int thePosX, int thePosY)
|
||||
{
|
||||
if (myView.IsNull()) { return; }
|
||||
|
||||
switch (myCurAction3d)
|
||||
const Graphic3d_Vec2i aNewPos (thePosX, thePosY);
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
case CurAction3d_DynamicRoation:
|
||||
{
|
||||
myView->Rotation (thePosX, thePosY);
|
||||
myView->Invalidate();
|
||||
myToRedraw = true;
|
||||
break;
|
||||
}
|
||||
case CurAction3d_DynamicPanning:
|
||||
{
|
||||
myView->Pan (thePosX - myMouseMax.x(), -(thePosY - myMouseMax.y()));
|
||||
myView->Invalidate();
|
||||
myToRedraw = true;
|
||||
myMouseMax.SetValues (thePosX, thePosY);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
myContext->MoveTo (thePosX, thePosY, myView, false);
|
||||
myToRedraw = true;
|
||||
break;
|
||||
}
|
||||
UpdateMousePosition (aNewPos, PressedMouseButtons(), LastMouseFlags(), false);
|
||||
}
|
||||
}
|
||||
|
@@ -25,20 +25,12 @@
|
||||
#include "GlfwOcctWindow.h"
|
||||
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <AIS_ViewController.hxx>
|
||||
#include <V3d_View.hxx>
|
||||
|
||||
//! Sample class creating 3D Viewer within GLFW window.
|
||||
class GlfwOcctView
|
||||
class GlfwOcctView : protected AIS_ViewController
|
||||
{
|
||||
public:
|
||||
enum CurAction3d
|
||||
{
|
||||
CurAction3d_Nothing,
|
||||
CurAction3d_DynamicZooming,
|
||||
CurAction3d_DynamicPanning,
|
||||
CurAction3d_DynamicRoation
|
||||
};
|
||||
|
||||
public:
|
||||
//! Default constructor.
|
||||
GlfwOcctView();
|
||||
@@ -115,11 +107,6 @@ private:
|
||||
Handle(V3d_View) myView;
|
||||
Handle(AIS_InteractiveContext) myContext;
|
||||
|
||||
CurAction3d myCurAction3d;
|
||||
Graphic3d_Vec2i myMouseMin;
|
||||
Graphic3d_Vec2i myMouseMax;
|
||||
bool myToRedraw;
|
||||
|
||||
};
|
||||
|
||||
#endif // _GlfwOcctView_Header
|
||||
|
@@ -134,17 +134,17 @@ void GlfwOcctWindow::Unmap() const
|
||||
// Function : DoResize
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
Aspect_TypeOfResize GlfwOcctWindow::DoResize() const
|
||||
Aspect_TypeOfResize GlfwOcctWindow::DoResize()
|
||||
{
|
||||
if (glfwGetWindowAttrib (myGlfwWindow, GLFW_VISIBLE) == 1)
|
||||
{
|
||||
int anXPos = 0, anYPos = 0, aWidth = 0, aHeight = 0;
|
||||
glfwGetWindowPos (myGlfwWindow, &anXPos, &anYPos);
|
||||
glfwGetWindowSize(myGlfwWindow, &aWidth, &aHeight);
|
||||
*const_cast<Standard_Integer*>(&myXLeft ) = anXPos;
|
||||
*const_cast<Standard_Integer*>(&myXRight ) = anXPos + aWidth;
|
||||
*const_cast<Standard_Integer*>(&myYTop ) = anYPos;
|
||||
*const_cast<Standard_Integer*>(&myYBottom) = anYPos + aHeight;
|
||||
myXLeft = anXPos;
|
||||
myXRight = anXPos + aWidth;
|
||||
myYTop = anYPos;
|
||||
myYBottom = anYPos + aHeight;
|
||||
}
|
||||
return Aspect_TOR_UNKNOWN;
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ public:
|
||||
virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return 0; }
|
||||
|
||||
//! Applies the resizing to the window <me>
|
||||
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE;
|
||||
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
|
||||
|
||||
//! Returns True if the window <me> is opened and False if the window is closed.
|
||||
virtual Standard_Boolean IsMapped() const Standard_OVERRIDE;
|
||||
|
@@ -44,7 +44,7 @@ public:
|
||||
virtual void Unmap() const Standard_OVERRIDE {}
|
||||
|
||||
//! Applies the resizing to the window <me>
|
||||
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
|
||||
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
|
||||
|
||||
//! Apply the mapping change to the window <me>
|
||||
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
|
||||
|
@@ -216,8 +216,7 @@ void GeomSources::DisplaySurface(CGeometryDoc* aDoc,
|
||||
|
||||
void GeomSources::ResetView(CGeometryDoc* aDoc)
|
||||
{
|
||||
aDoc->GetAISContext()->CurrentViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = aDoc->GetAISContext()->CurrentViewer()->ActiveViews().First();
|
||||
aView->Reset();
|
||||
}
|
||||
|
||||
|
@@ -68,8 +68,7 @@ void TexturesExt_Presentation::DoSample()
|
||||
void TexturesExt_Presentation::Init()
|
||||
{
|
||||
// initialize v3d_view so it displays TexturesExt well
|
||||
getViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = getViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = getViewer()->ActiveViews().First();
|
||||
aView->SetSize(ZVIEW_SIZE);
|
||||
|
||||
// getDocument()->UpdateResultMessageDlg("Textured Shape",
|
||||
|
@@ -1020,8 +1020,7 @@ void CViewer3dDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -1012,65 +1012,61 @@ aParams.NbMsaaSamples = aParams.NbMsaaSamples == 0 ? 8 : 0;\n\
|
||||
GetDocument()->UpdateResultMessageDlg("SetAntialiasingOn/SetAntialiasingOff",Message);
|
||||
}
|
||||
|
||||
void CViewer3dView::OnClearLights()
|
||||
void CViewer3dView::OnClearLights()
|
||||
{
|
||||
// Setting Off all viewer active lights
|
||||
TColStd_ListOfTransient lights;
|
||||
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())
|
||||
// Setting Off all viewer active lights
|
||||
V3d_ListOfLight lights;
|
||||
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())
|
||||
{
|
||||
lights.Append(myView->Viewer()->ActiveLight());
|
||||
lights.Append (anIter.Value());
|
||||
}
|
||||
TColStd_ListIteratorOfListOfTransient itrLights(lights);
|
||||
V3d_ListOfLightIterator itrLights(lights);
|
||||
for (; itrLights.More(); itrLights.Next())
|
||||
{
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
|
||||
myView->Viewer()->SetLightOff(light);
|
||||
myView->Viewer()->SetLightOff (itrLights.Value());
|
||||
}
|
||||
|
||||
// Setting Off all view active lights
|
||||
// Setting Off all view active lights
|
||||
lights.Clear();
|
||||
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())
|
||||
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())
|
||||
{
|
||||
lights.Append(myView->ActiveLight());
|
||||
lights.Append (anIter.Value());
|
||||
}
|
||||
itrLights.Initialize(lights);
|
||||
itrLights.Initialize (lights);
|
||||
for (; itrLights.More(); itrLights.Next())
|
||||
{
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
|
||||
myView->SetLightOff(light);
|
||||
myView->SetLightOff (itrLights.Value());
|
||||
}
|
||||
|
||||
myView->Viewer()->SetDefaultLights();// Setting the default lights on
|
||||
myView->Viewer()->SetDefaultLights(); // Setting the default lights on
|
||||
|
||||
NbActiveLights = 2;// There are 2 default active lights
|
||||
NbActiveLights = 2; // There are 2 default active lights
|
||||
|
||||
myView->Update();
|
||||
myView->Update();
|
||||
|
||||
TCollection_AsciiString Message("\
|
||||
// Setting Off all viewer active lights\n\
|
||||
TColStd_ListOfTransient lights;\n\
|
||||
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())\n\
|
||||
// Setting Off all viewer active lights\n\
|
||||
V3d_ListOfLight lights;\n\
|
||||
for (V3d_ListOfLightIterator anIter = myView->Viewer()->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
|
||||
{\n\
|
||||
lights.Append(myView->Viewer()->ActiveLight());\n\
|
||||
lights.Append (anIter.Value());\n\
|
||||
}\n\
|
||||
TColStd_ListIteratorOfListOfTransient itrLights(lights);\n\
|
||||
V3d_ListOfLightIterator itrLights(lights);\n\
|
||||
for (; itrLights.More(); itrLights.Next())\n\
|
||||
{\n\
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
|
||||
myView->Viewer()->SetLightOff(light);\n\
|
||||
myView->Viewer()->SetLightOff (itrLights.Value())\n\
|
||||
}\n\
|
||||
\n\
|
||||
// Setting Off all view active lights\n\
|
||||
// Setting Off all view active lights\n\
|
||||
lights.Clear();\n\
|
||||
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())\n\
|
||||
for (V3d_ListOfLightIterator anIter = myView->ActiveLightIterator(); anIter.More(); anIter.Next())\n\
|
||||
{\n\
|
||||
lights.Append(myView->ActiveLight());\n\
|
||||
lights.Append (anIter.Value());\n\
|
||||
}\n\
|
||||
itrLights.Initialize(lights);\n\
|
||||
for (; itrLights.More(); itrLights.Next())\n\
|
||||
{\n\
|
||||
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
|
||||
myView->SetLightOff(light);\n\
|
||||
myView->SetLightOff (itrLights.Value());\n\
|
||||
}\n\
|
||||
\n\
|
||||
myView->Viewer()->SetDefaultLights();// Setting the default lights on\n\
|
||||
|
@@ -413,8 +413,7 @@ void CTriangulationDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -230,8 +230,7 @@ void COCCDemoDoc::OnDumpView()
|
||||
pView->UpdateWindow();
|
||||
}
|
||||
|
||||
myViewer->InitActiveViews();
|
||||
Handle(V3d_View) aView = myViewer->ActiveView();
|
||||
Handle(V3d_View) aView = myViewer->ActiveViews().First();
|
||||
ExportView (aView);
|
||||
}
|
||||
|
||||
|
@@ -489,8 +489,7 @@ void OCC_3dBaseDoc::OnUpdateV3dButtons (CCmdUI* pCmdUI)
|
||||
// Common function to change raytracing params and redraw view
|
||||
void OCC_3dBaseDoc::OnObjectRayTracingAction()
|
||||
{
|
||||
myAISContext->CurrentViewer()->InitActiveViews();
|
||||
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveView();
|
||||
Handle(V3d_View) aView = myAISContext->CurrentViewer()->ActiveViews().First();
|
||||
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
|
||||
if (myRayTracingIsOn)
|
||||
aParams.Method = Graphic3d_RM_RAYTRACING;
|
||||
|
@@ -44,7 +44,7 @@ public:
|
||||
virtual void Unmap() const {}
|
||||
|
||||
//! Applies the resizing to the window <me>
|
||||
virtual Aspect_TypeOfResize DoResize() const { return Aspect_TOR_UNKNOWN; }
|
||||
virtual Aspect_TypeOfResize DoResize() { return Aspect_TOR_UNKNOWN; }
|
||||
|
||||
//! Apply the mapping change to the window <me>
|
||||
virtual Standard_Boolean DoMapping() const { return Standard_True; }
|
||||
|
@@ -81,7 +81,7 @@ void OcctWindow::Unmap() const
|
||||
// function : DoResize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Aspect_TypeOfResize OcctWindow::DoResize() const
|
||||
Aspect_TypeOfResize OcctWindow::DoResize()
|
||||
{
|
||||
int aMask = 0;
|
||||
Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
|
||||
@@ -126,10 +126,10 @@ Aspect_TypeOfResize OcctWindow::DoResize() const
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
*( ( Standard_Integer* )&myXLeft ) = myWidget->rect().left();
|
||||
*( ( Standard_Integer* )&myXRight ) = myWidget->rect().right();
|
||||
*( ( Standard_Integer* )&myYTop ) = myWidget->rect().top();
|
||||
*( ( Standard_Integer* )&myYBottom) = myWidget->rect().bottom();
|
||||
myXLeft = myWidget->rect().left();
|
||||
myXRight = myWidget->rect().right();
|
||||
myYTop = myWidget->rect().top();
|
||||
myYBottom = myWidget->rect().bottom();
|
||||
}
|
||||
|
||||
return aMode;
|
||||
|
@@ -51,7 +51,7 @@ public:
|
||||
virtual Aspect_Drawable NativeParentHandle() const;
|
||||
|
||||
//! Applies the resizing to the window <me>
|
||||
virtual Aspect_TypeOfResize DoResize() const;
|
||||
virtual Aspect_TypeOfResize DoResize();
|
||||
|
||||
//! Returns True if the window <me> is opened
|
||||
//! and False if the window is closed.
|
||||
|
@@ -276,7 +276,7 @@ blend result _model 2 _model_161
|
||||
# Show result
|
||||
pload VISUALIZATION
|
||||
vinit Driver1/Viewer1/View1
|
||||
vbackground -color 0.784314 0.784314 1
|
||||
vbackground -color C8C8FF
|
||||
vdisplay -dispMode 1 result
|
||||
vfit
|
||||
vaspects result -setFaceBoundaryDraw 1 -mostContinuity c2
|
||||
|
@@ -262,7 +262,7 @@ unifysamedom result p_1
|
||||
# Show result
|
||||
pload VISUALIZATION
|
||||
vinit Driver1/Viewer1/View1
|
||||
vbackground -color 0.784314 0.784314 1
|
||||
vbackground -color C8C8FF
|
||||
vdisplay -dispMode 1 result
|
||||
vfit
|
||||
vaspects result -setFaceBoundaryDraw 1
|
||||
|
@@ -68,18 +68,18 @@ vlight add directional direction 0 -10 0 head 1 color white
|
||||
vdisplay b1 b2 b3 b4 b5 b6 b7 b8 b9 b10
|
||||
|
||||
# set colors like in boxes of on OCC logo
|
||||
vsetcolor b1 0.8671875 0 0.16015625
|
||||
vsetcolor b2 0.96484375 0.8671875 0
|
||||
vsetcolor b3 0.609375 0.97734375 0.09375
|
||||
vsetcolor b4 0.90234375 0 0.48046875
|
||||
vsetcolor b5 0 0.48046875 0.73828125
|
||||
vsetcolor b6 0.578125 0 0.48046875
|
||||
vsetcolor b7 0.93359375 0.609375 0
|
||||
vsetcolor b8 0 0.70703125 0.9296875
|
||||
vsetcolor b9 0 0.64453125 0.48046875
|
||||
vsetcolor b10 0 0.48046875 0.73828125
|
||||
vsetcolor b1 DD0029
|
||||
vsetcolor b2 F6DD00
|
||||
vsetcolor b3 98F918
|
||||
vsetcolor b4 E9007A
|
||||
vsetcolor b5 007ABC
|
||||
vsetcolor b6 93007A
|
||||
vsetcolor b7 EE9800
|
||||
vsetcolor b8 00B489
|
||||
vsetcolor b9 00A47A
|
||||
vsetcolor b10 007ABC
|
||||
|
||||
# set material to plastic for better look
|
||||
for {set i 1} {$i <= 10} {incr i} {vsetmaterial b$i plastic}
|
||||
|
||||
vdrawtext label "Which\nbox\nis\ncloser\nto\nyou?" -pos 0 -6 -2 -color 0 0 0 -halign left -valign bottom -angle 0 -zoom 0 -height 40
|
||||
vdrawtext label "Which\nbox\nis\ncloser\nto\nyou?" -pos 0 -6 -2 -color BLACK -halign left -valign bottom -angle 0 -zoom 0 -height 40
|
||||
|
@@ -255,27 +255,27 @@ if [info exists i7_show_3dview] {
|
||||
vlight add directional direction 1 -1 -2 head 1
|
||||
|
||||
vdisplay case
|
||||
vsetcolor case 0.7 0.7 0.7
|
||||
vsetcolor case GRAY70
|
||||
|
||||
vdisplay title
|
||||
vsetcolor title 0.1 0.1 0.1
|
||||
vsetcolor title GRAY10
|
||||
|
||||
# board is mostly yellow (edges, triangle markers)
|
||||
foreach f [explode board f] { vdisplay $f; vsetcolor $f 0.7 0.5 0.3 }
|
||||
foreach f [explode board f] { vdisplay $f; vsetcolor $f B3803D }
|
||||
# top and bottom faces are light-green (outside) and dark-green (inside)
|
||||
vsetcolor board_4 0 0.6 0.55
|
||||
vsetcolor board_5 0 0.6 0.55
|
||||
vsetcolor board_12 0 0.3 0.33
|
||||
vsetcolor board_14 0 0.3 0.33
|
||||
vsetcolor board_4 00998C
|
||||
vsetcolor board_5 00998C
|
||||
vsetcolor board_12 004D54
|
||||
vsetcolor board_14 004D54
|
||||
|
||||
vdisplay rpads
|
||||
vsetcolor rpads 0.7 0.6 0.4
|
||||
vsetcolor rpads B39966
|
||||
|
||||
vdisplay bpads
|
||||
vsetcolor bpads 0.7 0.6 0.4
|
||||
vsetcolor bpads B39966
|
||||
|
||||
vdisplay brpk
|
||||
vsetcolor brpk 0.5 0.4 0.3
|
||||
vsetcolor brpk 80664D
|
||||
|
||||
donly board case rpads brpk; fit
|
||||
}
|
||||
@@ -287,17 +287,17 @@ pload OCAF XDE
|
||||
NewDocument D MDTV-XCAF
|
||||
|
||||
SetName D [XAddShape D board 0] "Board"
|
||||
foreach f [explode board f] { XSetColor D $f 0.7 0.5 0.3 }
|
||||
XSetColor D board_4 0 0.6 0.55
|
||||
XSetColor D board_5 0 0.6 0.55
|
||||
XSetColor D board_12 0 0.3 0.33
|
||||
XSetColor D board_14 0 0.3 0.33
|
||||
foreach f [explode board f] { XSetColor D $f B3803D }
|
||||
XSetColor D board_4 00998C
|
||||
XSetColor D board_5 00998C
|
||||
XSetColor D board_12 004D54
|
||||
XSetColor D board_14 004D54
|
||||
|
||||
SetName D [XAddShape D case 0] "Case"
|
||||
XSetColor D case 0.7 0.7 0.7
|
||||
XSetColor D case GRAY70
|
||||
|
||||
SetName D [XAddShape D title 0] "Case title"
|
||||
XSetColor D title 0.1 0.1 0.1
|
||||
XSetColor D title GRAY10
|
||||
|
||||
SetName D [XAddShape D rpads 1] "Top side contact pads"
|
||||
SetName D [XAddShape D bpads 1] "Bottom contact pads"
|
||||
@@ -306,17 +306,17 @@ SetName D [XFindShape D rpad] "Round pad"
|
||||
SetName D [XFindShape D Rpad] "Big round pad"
|
||||
SetName D [XFindShape D spad_1] "Square pad 1"
|
||||
SetName D [XFindShape D spad_2] "Square pad 2"
|
||||
XSetColor D rpad 0.7 0.6 0.4
|
||||
XSetColor D Rpad 0.7 0.6 0.4
|
||||
XSetColor D bpad 0.7 0.6 0.4
|
||||
XSetColor D spad_1 0.7 0.6 0.4
|
||||
XSetColor D spad_2 0.7 0.6 0.4
|
||||
XSetColor D rpad B39966
|
||||
XSetColor D Rpad B39966
|
||||
XSetColor D bpad B39966
|
||||
XSetColor D spad_1 B39966
|
||||
XSetColor D spad_2 B39966
|
||||
|
||||
SetName D [XAddShape D brpk 1] "Bottom packages"
|
||||
SetName D [XFindShape D rpk] "Bottom package"
|
||||
XSetColor D rpk1 0.7 0.7 0.7
|
||||
XSetColor D rpk2 0.5 0.4 0.3
|
||||
XSetColor D rpk3 0.7 0.7 0.7
|
||||
XSetColor D rpk1 GRAY70
|
||||
XSetColor D rpk2 80664D
|
||||
XSetColor D rpk3 GRAY70
|
||||
|
||||
XShow D
|
||||
vlight clear
|
||||
|
@@ -36,9 +36,7 @@ set anArrAngle [expr 3.14 * 12.0 / 180.0]
|
||||
|
||||
# Form dimension names list to set parameters with vdimparam command
|
||||
set aList {rd_1 rd_2 ad_1 ad_2 ad_3}
|
||||
for {set i 1} {$i <= 10} {incr i} {
|
||||
lappend aList ld_$i
|
||||
}
|
||||
for {set i 1} {$i <= 10} {incr i} { lappend aList ld_$i }
|
||||
|
||||
puts "Creating dimensions..."
|
||||
vdimension ld_1 -length -shapes bs_27 -plane xoy -color black -flyout -15
|
||||
@@ -67,29 +65,14 @@ foreach i $aList {
|
||||
vfit
|
||||
|
||||
puts "Displaying exported shapes..."
|
||||
vdisplay a b
|
||||
vsetdispmode a 1
|
||||
vsetdispmode b 1
|
||||
vdisplay -dispMode 1 a b
|
||||
vaspects a -setmaterial steel
|
||||
vaspects b -setmaterial bronze
|
||||
|
||||
puts "Clipping shapes for better view..."
|
||||
vclipplane create pa
|
||||
vclipplane change pa equation 0 0 1 0
|
||||
vclipplane change pa capping on
|
||||
vclipplane change pa capping color 0.9 0.9 0.9
|
||||
vclipplane set pa object a
|
||||
|
||||
vclipplane create pb
|
||||
vclipplane change pb equation 0 0 1 0
|
||||
vclipplane change pb capping on
|
||||
vclipplane change pb capping color 1.0 0.8 0.0
|
||||
vclipplane set pb object b
|
||||
|
||||
vclipplane change pa capping texname $aHatch
|
||||
vclipplane change pa capping texscale 0.05 -0.05
|
||||
vclipplane change pb capping texname $aHatch
|
||||
vclipplane change pb capping texscale 0.05 0.05
|
||||
vclipplane pa -set a -equation 0 0 1 0 -capping on -color GRAY90 -texName $aHatch -texScale 0.05 -0.05
|
||||
vclipplane pb -set b -equation 0 0 1 0 -capping on -color GOLD -texName $aHatch -texScale 0.05 -0.05
|
||||
|
||||
vbottom
|
||||
vrotate -0.3 -0.3 0
|
||||
|
@@ -77,14 +77,13 @@ SetName D $main "OCC Logo 2019"
|
||||
SetName D [XFindShape D sb] "Core"
|
||||
SetName D [XFindShape D tp] "Loop"
|
||||
SetName D [XFindShape D rs] "Connector"
|
||||
XSetColor D sb 1 0.21 0.32
|
||||
XSetColor D tp 0 0.667 0.855
|
||||
XSetColor D rs 0 0.45 0.69
|
||||
XSetColor D sb FF3652
|
||||
XSetColor D tp 00AADA
|
||||
XSetColor D rs 0073B0
|
||||
|
||||
# display
|
||||
vinit
|
||||
vsetcolorbg 1 1 1
|
||||
vsetdispmode 1
|
||||
XDisplay D
|
||||
vinit View1
|
||||
vbackground -color WHITE
|
||||
XDisplay -dispMode 1 D
|
||||
vtop
|
||||
vfit
|
||||
|
@@ -56,7 +56,7 @@ for { set aMarkerType 0 } { $aMarkerType <= 13 } { incr aMarkerType } {
|
||||
set aRow [expr $aMarkerType - 7]
|
||||
set aCol 5
|
||||
set aName [lindex $aMarkerTypeNames $aMarkerType]
|
||||
vdrawtext "$aName" "$aName" -pos 0 [expr $aRow + 0.5] 0 -color 0.5 1.0 1.0 -halign center -valign center -angle 000 -zoom 0 -height 12 -aspect bold -font $aLabelFont -noupdate
|
||||
vdrawtext "$aName" "$aName" -pos 0 [expr $aRow + 0.5] 0 -color 7FFFFF -halign center -valign center -angle 000 -zoom 0 -height 12 -aspect bold -font $aLabelFont -noupdate
|
||||
vdisplay -top -noupdate "$aName"
|
||||
if { $aMarkerType == 13 } {
|
||||
vmarkerstest m${aMarkerType}_${aCol} $aCol $aRow 0 PointsOnSide=1 FileName=$aCustom1
|
||||
|
@@ -4,36 +4,22 @@
|
||||
#Title: Material properties in viewer
|
||||
|
||||
set THE_MATERIALS {brass bronze copper gold jade neon_phc pewter obsidian plaster plastic satin silver steel stone chrome aluminium water glass diamond charcoal}
|
||||
set THE_COLORS {default red green blue1}
|
||||
set THE_COLORS {default red green blue}
|
||||
set THE_ROW_DIST 35
|
||||
|
||||
proc drawLabels {} {
|
||||
set x 20
|
||||
set y 15
|
||||
set r 0.098
|
||||
set g 0.098
|
||||
set b 0.098
|
||||
foreach aMatIter $::THE_MATERIALS {
|
||||
vdrawtext "$aMatIter" "$aMatIter" -pos $x $y 0 -color $r $g $b -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
|
||||
vdrawtext "$aMatIter" "$aMatIter" -pos $x $y 0 -color GRAY10 -halign right -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
|
||||
incr y 10
|
||||
}
|
||||
set x 40
|
||||
set y 5
|
||||
foreach aColIter $::THE_COLORS {
|
||||
if { $aColIter == "red" } {
|
||||
set r 1.0
|
||||
set g 0.0
|
||||
set b 0
|
||||
} elseif { $aColIter == "green" } {
|
||||
set r 0.0
|
||||
set g 1.0
|
||||
set b 0.0
|
||||
} elseif { $aColIter == "blue1" } {
|
||||
set r 0.0
|
||||
set g 0.0
|
||||
set b 1.0
|
||||
}
|
||||
vdrawtext "$aColIter" "$aColIter" -pos $x $y 0 -color $r $g $b -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
|
||||
set aLabColor "$aColIter"
|
||||
if { "$aColIter" == "default" } { set aLabColor BLACK }
|
||||
vdrawtext "$aColIter" "$aColIter" -pos $x $y 0 -color "$aLabColor" -halign center -valign center -angle 000 -zoom 0 -height 14 -aspect regular -font Arial
|
||||
incr x $::THE_ROW_DIST
|
||||
}
|
||||
}
|
||||
@@ -69,7 +55,7 @@ vclose ALL
|
||||
vinit View1 w=768 h=768
|
||||
vtop
|
||||
vglinfo
|
||||
vbackground -gradient 0.705882 0.784314 1 0.705882 0.705882 0.705882 -gradientMode VERTICAL
|
||||
vbackground -gradient B4C8FF B4B4B4 -gradientMode VERTICAL
|
||||
|
||||
vlight -change 0 -dir 0.577 -0.577 -0.577
|
||||
vrenderparams -msaa 8
|
||||
|
@@ -46,18 +46,17 @@ NewDocument D
|
||||
XAddShape D body_1
|
||||
XAddShape D core_1
|
||||
|
||||
#XSetColor D body_1 0. 0. 1.
|
||||
for {set i 1} {$i <= 26} {incr i} {XSetColor D body_1_$i 0. 0. 1.}
|
||||
XSetColor D body_1_1 0.9 0.5 0.4
|
||||
XSetColor D body_1_9 0.9 0.5 0.4
|
||||
for {set i 10} {$i <= 22} {incr i} {XSetColor D body_1_$i 0.6 0.7 0.0}
|
||||
XSetColor D core_1 0.1 0.1 1.
|
||||
foreach ff [explode core_1 f] { XSetColor D $ff 0.1 0.1 1. ; puts "set color $ff" }
|
||||
|
||||
XShow D
|
||||
for {set i 1} {$i <= 26} {incr i} {XSetColor D body_1_$i BLUE}
|
||||
XSetColor D body_1_1 E68066
|
||||
XSetColor D body_1_9 E68066
|
||||
for {set i 10} {$i <= 22} {incr i} {XSetColor D body_1_$i 99B300}
|
||||
XSetColor D core_1 1A1AFF
|
||||
foreach ff [explode core_1 f] { XSetColor D $ff 1A1AFF ; puts "set color $ff" }
|
||||
|
||||
vclear
|
||||
vinit View1
|
||||
XDisplay -dispMode 1 D -explore
|
||||
vfit
|
||||
vsetdispmode 1
|
||||
vrenderparams -msaa 8
|
||||
vbackground -color WHITE
|
||||
|
||||
|
@@ -28,19 +28,20 @@ SetName D [XFindShape D link]:2 "Nut instance 1"
|
||||
SetName D [XFindShape D link]:3 "Nut instance 2"
|
||||
|
||||
puts "- Pin will be white"
|
||||
XSetColor D [XFindShape D pin] 1 1 1
|
||||
XSetColor D [XFindShape D pin] WHITE
|
||||
puts "- Nut itself will be dark gray"
|
||||
XSetColor D [XFindShape D nut] 0.1 0.1 0.1
|
||||
XSetColor D [XFindShape D nut] GRAY10
|
||||
puts "- Nut instance #1 will be red"
|
||||
XSetColor D [XFindShape D link]:2 1 0 0
|
||||
XSetColor D [XFindShape D link]:2 RED
|
||||
puts "- Nut instance #2 will be green"
|
||||
XSetColor D [XFindShape D link]:3 0 1 0
|
||||
XSetColor D [XFindShape D link]:3 GREEN
|
||||
|
||||
puts "Starting DF browser..."
|
||||
DFBrowse D
|
||||
puts "Expand the document tree to see its structure and assigned names"
|
||||
|
||||
puts "Showing assembly in 3d view..."
|
||||
XShow D
|
||||
vclear
|
||||
vinit View1
|
||||
XDisplay -dispMode 1 D -explore
|
||||
vfit
|
||||
vsetdispmode 1
|
||||
|
2
samples/webgl/.gitignore
vendored
Normal file
2
samples/webgl/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/work
|
66
samples/webgl/CMakeLists.txt
Normal file
66
samples/webgl/CMakeLists.txt
Normal file
@@ -0,0 +1,66 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
project(occt-webgl-sample)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(APP_VERSION_MAJOR 1)
|
||||
set(APP_VERSION_MINOR 0)
|
||||
set(APP_TARGET occt-webgl-sample)
|
||||
|
||||
# customize build
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_WEBGL2=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s SAFE_HEAP=1")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_EXIT_RUNTIME=1")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s TOTAL_MEMORY=16MB")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ABORTING_MALLOC=0")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s FORCE_FILESYSTEM=1")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --preload-file myFile")
|
||||
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
|
||||
file(GLOB SOURCES
|
||||
*.h
|
||||
*.cpp
|
||||
)
|
||||
source_group ("Headers" FILES
|
||||
WasmOcctView.h)
|
||||
source_group ("Sources" FILES
|
||||
WasmOcctView.cpp
|
||||
main.cpp)
|
||||
|
||||
# FreeType
|
||||
find_package(freetype REQUIRED NO_DEFAULT_PATH)
|
||||
if(freetype_FOUND)
|
||||
message (STATUS "Using FreeType from \"${freetype_DIR}\"" )
|
||||
else()
|
||||
message(WARNING "Could not find FreeType, please set freetype_DIR variable." )
|
||||
endif()
|
||||
|
||||
# Open CASCADE Technology
|
||||
find_package(OpenCASCADE REQUIRED NO_DEFAULT_PATH)
|
||||
if(OpenCASCADE_FOUND)
|
||||
message (STATUS "Using OpenCASCADE from \"${OpenCASCADE_DIR}\"" )
|
||||
INCLUDE_DIRECTORIES(${OpenCASCADE_INCLUDE_DIR})
|
||||
LINK_DIRECTORIES(${OpenCASCADE_LIBRARY_DIR})
|
||||
else()
|
||||
message(WARNING "Could not find OpenCASCADE, please set OpenCASCADE_DIR variable." )
|
||||
set(OCCT_LIBRARY_DIR)
|
||||
set(OCCT_BIN_DIR)
|
||||
endif()
|
||||
|
||||
set(OpenCASCADE_LIBS TKRWMesh TKBinXCAF TKBin TKBinL TKOpenGl TKXCAF TKVCAF TKCAF TKV3d TKHLR TKMesh TKService TKShHealing TKPrim TKTopAlgo TKGeomAlgo TKBRep TKGeomBase TKG3d TKG2d TKMath TKLCAF TKCDF TKernel)
|
||||
|
||||
add_executable(${APP_TARGET} ${SOURCES})
|
||||
target_link_libraries(
|
||||
${APP_TARGET}
|
||||
${OpenCASCADE_LIBS}
|
||||
freetype
|
||||
)
|
||||
set_target_properties(${APP_TARGET} PROPERTIES LINK_FLAGS "-s EXPORTED_FUNCTIONS=['_main','_onFileDataRead'] -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']")
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.wasm DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
install(FILES occt-webgl-sample.html DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
install(FILES ${OpenCASCADE_RESOURCE_DIR}/DrawResources/OCC_logo.png DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
install(FILES ${OpenCASCADE_RESOURCE_DIR}/DrawResources/lamp.ico DESTINATION ${CMAKE_INSTALL_PREFIX})
|
28
samples/webgl/ReadMe.md
Normal file
28
samples/webgl/ReadMe.md
Normal file
@@ -0,0 +1,28 @@
|
||||
OCCT WebGL Viewer sample {#occt_samples_webgl}
|
||||
==================
|
||||
|
||||
This sample demonstrates simple way of using OCCT libraries in Web application written in C++ and translated into WebAssembly module using Emscripten SDK (emsdk):
|
||||
https://emscripten.org/
|
||||
|
||||
Sample consists of the Open CASCADE 3D Viewer with a button for opening a model in BREP format.
|
||||
The sample requires a WebGL 2.0 capable browser supporting WebAssembly 1.0 (Wasm).
|
||||
|
||||
Installation and configuration:
|
||||
1. Install Emscripten SDK and activate minimal configuration (Python, Java and CLang) following *emsdk* documentation. Activate also MinGW when building sample on Windows host.
|
||||
2. Build (using *emsdk*) or download FreeType static library.
|
||||
3. Configure CMake for building Open CASCADE Technology (OCCT) static libraries (BUILD_LIBRARY_TYPE="Static").
|
||||
For this, activate *emsdk* command prompt, configure CMake for building OCCT using cross-compilation toolchain, disable *BUILD_MODULE_Draw*.
|
||||
4. Perform building and installation steps.
|
||||
~~~~~
|
||||
> ${EMSDK}/fastcomp/emscripten/cmake/Modules/Platform/Emscripten.cmake
|
||||
~~~~~
|
||||
5. Configure CMake for building this WebGL sample using *emsdk* with paths to OCCT and FreeType. Perform building and installation steps.
|
||||
6. Copy data/occ/Ball.brep from OCCT into "samples" folder within WebGL sample installation path.
|
||||
7. Navigate to installation folder and start web server from it; Python coming with *emsdk* can be used for this purpose:
|
||||
~~~~~
|
||||
> python -m SimpleHTTPServer 8080
|
||||
~~~~~
|
||||
8. Open compatible browser and enter path taking into account your web server settings:
|
||||
~~~~~
|
||||
> http://localhost:8080/occt-webgl-sample.html
|
||||
~~~~~
|
678
samples/webgl/WasmOcctView.cpp
Normal file
678
samples/webgl/WasmOcctView.cpp
Normal file
@@ -0,0 +1,678 @@
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of the examples of the Open CASCADE Technology software library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
#include "WasmOcctView.h"
|
||||
|
||||
#include "WasmVKeys.h"
|
||||
|
||||
#include <AIS_Shape.hxx>
|
||||
#include <AIS_ViewCube.hxx>
|
||||
#include <Aspect_Handle.hxx>
|
||||
#include <Aspect_DisplayConnection.hxx>
|
||||
#include <Aspect_NeutralWindow.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <OpenGl_GraphicDriver.hxx>
|
||||
#include <Prs3d_DatumAspect.hxx>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define THE_CANVAS_ID "canvas"
|
||||
|
||||
namespace
|
||||
{
|
||||
EM_JS(int, jsCanvasGetWidth, (), {
|
||||
return canvas.width;
|
||||
});
|
||||
|
||||
EM_JS(int, jsCanvasGetHeight, (), {
|
||||
return canvas.height;
|
||||
});
|
||||
|
||||
EM_JS(float, jsDevicePixelRatio, (), {
|
||||
var aDevicePixelRatio = window.devicePixelRatio || 1;
|
||||
return aDevicePixelRatio;
|
||||
});
|
||||
|
||||
//! Return cavas size in pixels.
|
||||
static Graphic3d_Vec2i jsCanvasSize()
|
||||
{
|
||||
return Graphic3d_Vec2i (jsCanvasGetWidth(), jsCanvasGetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : WasmOcctView
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
WasmOcctView::WasmOcctView()
|
||||
: myDevicePixelRatio (1.0f),
|
||||
myUpdateRequests (0)
|
||||
{
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : ~WasmOcctView
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
WasmOcctView::~WasmOcctView()
|
||||
{
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : run
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::run()
|
||||
{
|
||||
initWindow();
|
||||
initViewer();
|
||||
initDemoScene();
|
||||
if (myView.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myView->MustBeResized();
|
||||
myView->Redraw();
|
||||
|
||||
// There is no inifinite message loop, main() will return from here immediately.
|
||||
// Tell that our Module should be left loaded and handle events through callbacks.
|
||||
//emscripten_set_main_loop (redrawView, 60, 1);
|
||||
//emscripten_set_main_loop (redrawView, -1, 1);
|
||||
EM_ASM(Module['noExitRuntime'] = true);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : initWindow
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::initWindow()
|
||||
{
|
||||
myDevicePixelRatio = jsDevicePixelRatio();
|
||||
myCanvasId = THE_CANVAS_ID;
|
||||
const char* aTargetId = !myCanvasId.IsEmpty() ? myCanvasId.ToCString() : NULL;
|
||||
const EM_BOOL toUseCapture = EM_TRUE;
|
||||
emscripten_set_resize_callback (NULL, this, toUseCapture, onResizeCallback);
|
||||
|
||||
emscripten_set_mousedown_callback (NULL, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_mouseup_callback (NULL, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_mousemove_callback (NULL, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_dblclick_callback (aTargetId, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_click_callback (aTargetId, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_mouseenter_callback (aTargetId, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_mouseleave_callback (aTargetId, this, toUseCapture, onMouseCallback);
|
||||
emscripten_set_wheel_callback (aTargetId, this, toUseCapture, onWheelCallback);
|
||||
|
||||
emscripten_set_touchstart_callback (aTargetId, this, toUseCapture, onTouchCallback);
|
||||
emscripten_set_touchend_callback (aTargetId, this, toUseCapture, onTouchCallback);
|
||||
emscripten_set_touchmove_callback (aTargetId, this, toUseCapture, onTouchCallback);
|
||||
emscripten_set_touchcancel_callback(aTargetId, this, toUseCapture, onTouchCallback);
|
||||
|
||||
//emscripten_set_keypress_callback (NULL, this, toUseCapture, onKeyCallback);
|
||||
emscripten_set_keydown_callback (NULL, this, toUseCapture, onKeyDownCallback);
|
||||
emscripten_set_keyup_callback (NULL, this, toUseCapture, onKeyUpCallback);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : dumpGlInfo
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::dumpGlInfo (bool theIsBasic)
|
||||
{
|
||||
TColStd_IndexedDataMapOfStringString aGlCapsDict;
|
||||
myView->DiagnosticInformation (aGlCapsDict, theIsBasic ? Graphic3d_DiagnosticInfo_Basic : Graphic3d_DiagnosticInfo_Complete);
|
||||
if (theIsBasic)
|
||||
{
|
||||
TCollection_AsciiString aViewport;
|
||||
aGlCapsDict.FindFromKey ("Viewport", aViewport);
|
||||
aGlCapsDict.Clear();
|
||||
aGlCapsDict.Add ("Viewport", aViewport);
|
||||
}
|
||||
aGlCapsDict.Add ("Display scale", TCollection_AsciiString(myDevicePixelRatio));
|
||||
|
||||
// beautify output
|
||||
{
|
||||
TCollection_AsciiString* aGlVer = aGlCapsDict.ChangeSeek ("GLversion");
|
||||
TCollection_AsciiString* aGlslVer = aGlCapsDict.ChangeSeek ("GLSLversion");
|
||||
if (aGlVer != NULL
|
||||
&& aGlslVer != NULL)
|
||||
{
|
||||
*aGlVer = *aGlVer + " [GLSL: " + *aGlslVer + "]";
|
||||
aGlslVer->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
TCollection_AsciiString anInfo;
|
||||
for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aGlCapsDict); aValueIter.More(); aValueIter.Next())
|
||||
{
|
||||
if (!aValueIter.Value().IsEmpty())
|
||||
{
|
||||
if (!anInfo.IsEmpty())
|
||||
{
|
||||
anInfo += "\n";
|
||||
}
|
||||
anInfo += aValueIter.Key() + ": " + aValueIter.Value();
|
||||
}
|
||||
}
|
||||
|
||||
::Message::DefaultMessenger()->Send (anInfo, Message_Warning);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : initPixelScaleRatio
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::initPixelScaleRatio()
|
||||
{
|
||||
SetTouchToleranceScale (myDevicePixelRatio);
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
myView->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
|
||||
}
|
||||
if (!myContext.IsNull())
|
||||
{
|
||||
myContext->SetPixelTolerance (int(myDevicePixelRatio * 6.0));
|
||||
if (!myViewCube.IsNull())
|
||||
{
|
||||
static const double THE_CUBE_SIZE = 60.0;
|
||||
myViewCube->SetSize (myDevicePixelRatio * THE_CUBE_SIZE, false);
|
||||
myViewCube->SetBoxFacetExtension (myViewCube->Size() * 0.15);
|
||||
myViewCube->SetAxesPadding (myViewCube->Size() * 0.10);
|
||||
myViewCube->SetFontHeight (THE_CUBE_SIZE * 0.16);
|
||||
if (myViewCube->HasInteractiveContext())
|
||||
{
|
||||
myContext->Redisplay (myViewCube, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : initViewer
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
bool WasmOcctView::initViewer()
|
||||
{
|
||||
// Build with "--preload-file MyFontFile.ttf" option
|
||||
// and register font in Font Manager to use custom font(s).
|
||||
/*const char* aFontPath = "MyFontFile.ttf";
|
||||
if (Handle(Font_SystemFont) aFont = Font_FontMgr::GetInstance()->CheckFont (aFontPath))
|
||||
{
|
||||
Font_FontMgr::GetInstance()->RegisterFont (aFont, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: font '") + aFontPath + "' is not found", Message_Fail);
|
||||
}*/
|
||||
|
||||
Handle(Aspect_DisplayConnection) aDisp;
|
||||
Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (aDisp, false);
|
||||
aDriver->ChangeOptions().buffersNoSwap = true; // swap has no effect in WebGL
|
||||
if (!aDriver->InitContext())
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: EGL initialization failed"), Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
Handle(V3d_Viewer) aViewer = new V3d_Viewer (aDriver);
|
||||
aViewer->SetComputedMode (false);
|
||||
aViewer->SetDefaultShadingModel (Graphic3d_TOSM_FRAGMENT);
|
||||
aViewer->SetDefaultLights();
|
||||
aViewer->SetLightOn();
|
||||
|
||||
Handle(Aspect_NeutralWindow) aWindow = new Aspect_NeutralWindow();
|
||||
Graphic3d_Vec2i aWinSize = jsCanvasSize();
|
||||
if (aWinSize.x() < 10 || aWinSize.y() < 10)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning: invalid canvas size"), Message_Warning);
|
||||
}
|
||||
aWindow->SetSize (aWinSize.x(), aWinSize.y());
|
||||
|
||||
myTextStyle = new Prs3d_TextAspect();
|
||||
myTextStyle->SetFont (Font_NOF_ASCII_MONO);
|
||||
myTextStyle->SetHeight (12);
|
||||
myTextStyle->Aspect()->SetColor (Quantity_NOC_GRAY95);
|
||||
myTextStyle->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
|
||||
myTextStyle->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
|
||||
myTextStyle->Aspect()->SetTextFontAspect (Font_FA_Bold);
|
||||
myTextStyle->Aspect()->SetTextZoomable (false);
|
||||
myTextStyle->SetHorizontalJustification (Graphic3d_HTA_LEFT);
|
||||
myTextStyle->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
|
||||
|
||||
myView = new V3d_View (aViewer);
|
||||
myView->SetImmediateUpdate (false);
|
||||
myView->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
|
||||
myView->ChangeRenderingParams().ToShowStats = true;
|
||||
myView->ChangeRenderingParams().StatsTextAspect = myTextStyle->Aspect();
|
||||
myView->ChangeRenderingParams().StatsTextHeight = (int )myTextStyle->Height();
|
||||
myView->SetWindow (aWindow);
|
||||
dumpGlInfo (false);
|
||||
|
||||
myContext = new AIS_InteractiveContext (aViewer);
|
||||
initPixelScaleRatio();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : initDemoScene
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::initDemoScene()
|
||||
{
|
||||
if (myContext.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//myView->TriedronDisplay (Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_WIREFRAME);
|
||||
|
||||
myViewCube = new AIS_ViewCube();
|
||||
// presentation parameters
|
||||
initPixelScaleRatio();
|
||||
myViewCube->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_RIGHT_LOWER, Graphic3d_Vec2i (100, 100)));
|
||||
myViewCube->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
|
||||
myViewCube->Attributes()->DatumAspect()->SetTextAspect (myTextStyle);
|
||||
// animation parameters
|
||||
myViewCube->SetViewAnimation (myViewAnimation);
|
||||
myViewCube->SetFixedAnimationLoop (false);
|
||||
myViewCube->SetAutoStartAnimation (true);
|
||||
myContext->Display (myViewCube, false);
|
||||
|
||||
// Build with "--preload-file MySampleFile.brep" option to load some shapes here.
|
||||
}
|
||||
|
||||
|
||||
// ================================================================
|
||||
// Function : updateView
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::updateView()
|
||||
{
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
if (++myUpdateRequests == 1)
|
||||
{
|
||||
emscripten_async_call (onRedrawView, this, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : redrawView
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::redrawView()
|
||||
{
|
||||
if (!myView.IsNull())
|
||||
{
|
||||
FlushViewEvents (myContext, myView, true);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : handleViewRedraw
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
void WasmOcctView::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
myUpdateRequests = 0;
|
||||
AIS_ViewController::handleViewRedraw (theCtx, theView);
|
||||
if (myToAskNextFrame)
|
||||
{
|
||||
// ask more frames
|
||||
++myUpdateRequests;
|
||||
emscripten_async_call (onRedrawView, this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onResizeEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onResizeEvent (int theEventType, const EmscriptenUiEvent* theEvent)
|
||||
{
|
||||
(void )theEventType; // EMSCRIPTEN_EVENT_RESIZE or EMSCRIPTEN_EVENT_CANVASRESIZED
|
||||
(void )theEvent;
|
||||
if (myView.IsNull())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast (myView->Window());
|
||||
Graphic3d_Vec2i aWinSizeOld, aWinSizeNew (jsCanvasSize());
|
||||
if (aWinSizeNew.x() < 10 || aWinSizeNew.y() < 10)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning: invalid canvas size"), Message_Warning);
|
||||
}
|
||||
aWindow->Size (aWinSizeOld.x(), aWinSizeOld.y());
|
||||
const float aPixelRatio = jsDevicePixelRatio();
|
||||
if (aWinSizeNew != aWinSizeOld
|
||||
|| aPixelRatio != myDevicePixelRatio)
|
||||
{
|
||||
if (myDevicePixelRatio != aPixelRatio)
|
||||
{
|
||||
myDevicePixelRatio = aPixelRatio;
|
||||
initPixelScaleRatio();
|
||||
}
|
||||
aWindow->SetSize (aWinSizeNew.x(), aWinSizeNew.y());
|
||||
myView->MustBeResized();
|
||||
myView->Invalidate();
|
||||
myView->Redraw();
|
||||
dumpGlInfo (true);
|
||||
}
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onMouseEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onMouseEvent (int theEventType, const EmscriptenMouseEvent* theEvent)
|
||||
{
|
||||
if (myView.IsNull())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
myView->Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (theEvent->canvasX, theEvent->canvasY));
|
||||
Aspect_VKeyFlags aFlags = 0;
|
||||
if (theEvent->ctrlKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_CTRL; }
|
||||
if (theEvent->shiftKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_SHIFT; }
|
||||
if (theEvent->altKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_ALT; }
|
||||
if (theEvent->metaKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_META; }
|
||||
|
||||
const bool isEmulated = false;
|
||||
const Aspect_VKeyMouse aButtons = WasmVKeys_MouseButtonsFromNative (theEvent->buttons);
|
||||
switch (theEventType)
|
||||
{
|
||||
case EMSCRIPTEN_EVENT_MOUSEMOVE:
|
||||
{
|
||||
if ((aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|
||||
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
|
||||
&& PressedMouseButtons() == Aspect_VKeyMouse_NONE)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
if (UpdateMousePosition (aNewPos, aButtons, aFlags, isEmulated))
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_MOUSEDOWN:
|
||||
case EMSCRIPTEN_EVENT_MOUSEUP:
|
||||
{
|
||||
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|
||||
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
if (UpdateMouseButtons (aNewPos, aButtons, aFlags, isEmulated))
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_CLICK:
|
||||
case EMSCRIPTEN_EVENT_DBLCLICK:
|
||||
{
|
||||
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|
||||
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_MOUSEENTER:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_MOUSELEAVE:
|
||||
{
|
||||
// there is no SetCapture() support, so that mouse unclick events outside canvas will not arrive,
|
||||
// so we have to forget current state...
|
||||
if (UpdateMouseButtons (aNewPos, Aspect_VKeyMouse_NONE, aFlags, isEmulated))
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onWheelEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onWheelEvent (int theEventType, const EmscriptenWheelEvent* theEvent)
|
||||
{
|
||||
if (myView.IsNull()
|
||||
|| theEventType != EMSCRIPTEN_EVENT_WHEEL)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
myView->Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (theEvent->mouse.canvasX, theEvent->mouse.canvasY));
|
||||
if (aNewPos.x() < 0 || aNewPos.x() > aWinSize.x()
|
||||
|| aNewPos.y() < 0 || aNewPos.y() > aWinSize.y())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
double aDelta = 0.0;
|
||||
switch (theEvent->deltaMode)
|
||||
{
|
||||
case DOM_DELTA_PIXEL:
|
||||
{
|
||||
aDelta = theEvent->deltaY / (5.0 * myDevicePixelRatio);
|
||||
break;
|
||||
}
|
||||
case DOM_DELTA_LINE:
|
||||
{
|
||||
aDelta = theEvent->deltaY * 8.0;
|
||||
break;
|
||||
}
|
||||
case DOM_DELTA_PAGE:
|
||||
{
|
||||
aDelta = theEvent->deltaY >= 0.0 ? 24.0 : -24.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UpdateZoom (Aspect_ScrollDelta (aNewPos, -aDelta)))
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onTouchEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onTouchEvent (int theEventType, const EmscriptenTouchEvent* theEvent)
|
||||
{
|
||||
const double aClickTolerance = 5.0;
|
||||
if (myView.IsNull())
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
myView->Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
bool hasUpdates = false;
|
||||
for (int aTouchIter = 0; aTouchIter < theEvent->numTouches; ++aTouchIter)
|
||||
{
|
||||
const EmscriptenTouchPoint& aTouch = theEvent->touches[aTouchIter];
|
||||
if (!aTouch.isChanged)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Standard_Size aTouchId = (Standard_Size )aTouch.identifier;
|
||||
const Graphic3d_Vec2i aNewPos = convertPointToBacking (Graphic3d_Vec2i (aTouch.canvasX, aTouch.canvasY));
|
||||
switch (theEventType)
|
||||
{
|
||||
case EMSCRIPTEN_EVENT_TOUCHSTART:
|
||||
{
|
||||
if (aNewPos.x() >= 0 && aNewPos.x() < aWinSize.x()
|
||||
&& aNewPos.y() >= 0 && aNewPos.y() < aWinSize.y())
|
||||
{
|
||||
hasUpdates = true;
|
||||
AddTouchPoint (aTouchId, Graphic3d_Vec2d (aNewPos));
|
||||
myClickTouch.From.SetValues (-1.0, -1.0);
|
||||
if (myTouchPoints.Extent() == 1)
|
||||
{
|
||||
myClickTouch.From = Graphic3d_Vec2d (aNewPos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_TOUCHMOVE:
|
||||
{
|
||||
const int anOldIndex = myTouchPoints.FindIndex (aTouchId);
|
||||
if (anOldIndex != 0)
|
||||
{
|
||||
hasUpdates = true;
|
||||
UpdateTouchPoint (aTouchId, Graphic3d_Vec2d (aNewPos));
|
||||
if (myTouchPoints.Extent() == 1
|
||||
&& (myClickTouch.From - Graphic3d_Vec2d (aNewPos)).cwiseAbs().maxComp() > aClickTolerance)
|
||||
{
|
||||
myClickTouch.From.SetValues (-1.0, -1.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EMSCRIPTEN_EVENT_TOUCHEND:
|
||||
case EMSCRIPTEN_EVENT_TOUCHCANCEL:
|
||||
{
|
||||
if (RemoveTouchPoint (aTouchId))
|
||||
{
|
||||
if (myTouchPoints.IsEmpty()
|
||||
&& myClickTouch.From.minComp() >= 0.0)
|
||||
{
|
||||
if (myDoubleTapTimer.IsStarted()
|
||||
&& myDoubleTapTimer.ElapsedTime() <= myMouseDoubleClickInt)
|
||||
{
|
||||
myView->FitAll (0.01, false);
|
||||
myView->Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
myDoubleTapTimer.Stop();
|
||||
myDoubleTapTimer.Reset();
|
||||
myDoubleTapTimer.Start();
|
||||
SelectInViewer (Graphic3d_Vec2i (myClickTouch.From), false);
|
||||
}
|
||||
}
|
||||
hasUpdates = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasUpdates)
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
return hasUpdates || !myTouchPoints.IsEmpty() ? EM_TRUE : EM_FALSE;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onKeyDownEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onKeyDownEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent)
|
||||
{
|
||||
if (myView.IsNull()
|
||||
|| theEventType != EMSCRIPTEN_EVENT_KEYDOWN) // EMSCRIPTEN_EVENT_KEYPRESS
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
const double aTimeStamp = EventTime();
|
||||
const Aspect_VKey aVKey = WasmVKeys_VirtualKeyFromNative (theEvent->keyCode);
|
||||
if (aVKey == Aspect_VKey_UNKNOWN)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
if (theEvent->repeat == EM_FALSE)
|
||||
{
|
||||
myKeys.KeyDown (aVKey, aTimeStamp);
|
||||
}
|
||||
|
||||
if (Aspect_VKey2Modifier (aVKey) == 0)
|
||||
{
|
||||
// normal key
|
||||
}
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Function : onKeyUpEvent
|
||||
// Purpose :
|
||||
// ================================================================
|
||||
EM_BOOL WasmOcctView::onKeyUpEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent)
|
||||
{
|
||||
if (myView.IsNull()
|
||||
|| theEventType != EMSCRIPTEN_EVENT_KEYUP)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
const double aTimeStamp = EventTime();
|
||||
const Aspect_VKey aVKey = WasmVKeys_VirtualKeyFromNative (theEvent->keyCode);
|
||||
if (aVKey == Aspect_VKey_UNKNOWN)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
if (theEvent->repeat == EM_TRUE)
|
||||
{
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
const unsigned int aModif = myKeys.Modifiers();
|
||||
myKeys.KeyUp (aVKey, aTimeStamp);
|
||||
if (Aspect_VKey2Modifier (aVKey) == 0)
|
||||
{
|
||||
// normal key released
|
||||
switch (aVKey | aModif)
|
||||
{
|
||||
case Aspect_VKey_F:
|
||||
{
|
||||
myView->FitAll (0.01, false);
|
||||
myView->Invalidate();
|
||||
updateView();
|
||||
return EM_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return EM_FALSE;
|
||||
}
|
157
samples/webgl/WasmOcctView.h
Normal file
157
samples/webgl/WasmOcctView.h
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of the examples of the Open CASCADE Technology software library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
#ifndef _WasmOcctView_HeaderFile
|
||||
#define _WasmOcctView_HeaderFile
|
||||
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <AIS_ViewController.hxx>
|
||||
#include <V3d_View.hxx>
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
class AIS_ViewCube;
|
||||
|
||||
//! Sample class creating 3D Viewer within Emscripten canvas.
|
||||
class WasmOcctView : protected AIS_ViewController
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
WasmOcctView();
|
||||
|
||||
//! Destructor.
|
||||
virtual ~WasmOcctView();
|
||||
|
||||
//! Main application entry point.
|
||||
void run();
|
||||
|
||||
//! Return interactive context.
|
||||
const Handle(AIS_InteractiveContext)& Context() const { return myContext; }
|
||||
|
||||
//! Return view.
|
||||
const Handle(V3d_View)& View() const { return myView; }
|
||||
|
||||
//! Return device pixel ratio for handling high DPI displays.
|
||||
float DevicePixelRatio() const { return myDevicePixelRatio; }
|
||||
|
||||
private:
|
||||
|
||||
//! Create window.
|
||||
void initWindow();
|
||||
|
||||
//! Create 3D Viewer.
|
||||
bool initViewer();
|
||||
|
||||
//! Fill 3D Viewer with a DEMO items.
|
||||
void initDemoScene();
|
||||
|
||||
//! Application event loop.
|
||||
void mainloop();
|
||||
|
||||
//! Request view redrawing.
|
||||
void updateView();
|
||||
|
||||
//! Flush events and redraw view.
|
||||
void redrawView();
|
||||
|
||||
//! Handle view redraw.
|
||||
virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView) override;
|
||||
|
||||
//! Dump WebGL context information.
|
||||
void dumpGlInfo (bool theIsBasic);
|
||||
|
||||
//! Initialize pixel scale ratio.
|
||||
void initPixelScaleRatio();
|
||||
|
||||
//! Return point from logical units to backing store.
|
||||
Graphic3d_Vec2d convertPointToBacking (const Graphic3d_Vec2d& thePnt) const
|
||||
{
|
||||
return thePnt * myDevicePixelRatio;
|
||||
}
|
||||
|
||||
//! Return point from logical units to backing store.
|
||||
Graphic3d_Vec2i convertPointToBacking (const Graphic3d_Vec2i& thePnt) const
|
||||
{
|
||||
Graphic3d_Vec2d aPnt = Graphic3d_Vec2d (thePnt) * myDevicePixelRatio + Graphic3d_Vec2d (0.5);
|
||||
return Graphic3d_Vec2i (aPnt);
|
||||
}
|
||||
|
||||
//! @name Emscripten callbacks
|
||||
private:
|
||||
//! Window resize event.
|
||||
EM_BOOL onResizeEvent (int theEventType, const EmscriptenUiEvent* theEvent);
|
||||
|
||||
//! Mouse event.
|
||||
EM_BOOL onMouseEvent (int theEventType, const EmscriptenMouseEvent* theEvent);
|
||||
|
||||
//! Scroll event.
|
||||
EM_BOOL onWheelEvent (int theEventType, const EmscriptenWheelEvent* theEvent);
|
||||
|
||||
//! Touch event.
|
||||
EM_BOOL onTouchEvent (int theEventType, const EmscriptenTouchEvent* theEvent);
|
||||
|
||||
//! Key down event.
|
||||
EM_BOOL onKeyDownEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent);
|
||||
|
||||
//! Key up event.
|
||||
EM_BOOL onKeyUpEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent);
|
||||
|
||||
//! @name Emscripten callbacks (static functions)
|
||||
private:
|
||||
|
||||
static EM_BOOL onResizeCallback (int theEventType, const EmscriptenUiEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onResizeEvent (theEventType, theEvent); }
|
||||
|
||||
static void onRedrawView (void* theView)
|
||||
{ return ((WasmOcctView* )theView)->redrawView(); }
|
||||
|
||||
static EM_BOOL onMouseCallback (int theEventType, const EmscriptenMouseEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onMouseEvent (theEventType, theEvent); }
|
||||
|
||||
static EM_BOOL onWheelCallback (int theEventType, const EmscriptenWheelEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onWheelEvent (theEventType, theEvent); }
|
||||
|
||||
static EM_BOOL onTouchCallback (int theEventType, const EmscriptenTouchEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onTouchEvent (theEventType, theEvent); }
|
||||
|
||||
static EM_BOOL onKeyDownCallback (int theEventType, const EmscriptenKeyboardEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onKeyDownEvent (theEventType, theEvent); }
|
||||
|
||||
static EM_BOOL onKeyUpCallback (int theEventType, const EmscriptenKeyboardEvent* theEvent, void* theView)
|
||||
{ return ((WasmOcctView* )theView)->onKeyUpEvent (theEventType, theEvent); }
|
||||
|
||||
private:
|
||||
|
||||
Handle(AIS_InteractiveContext) myContext; //!< interactive context
|
||||
Handle(V3d_View) myView; //!< 3D view
|
||||
Handle(Prs3d_TextAspect) myTextStyle; //!< text style for OSD elements
|
||||
Handle(AIS_ViewCube) myViewCube; //!< view cube object
|
||||
TCollection_AsciiString myCanvasId; //!< canvas element id on HTML page
|
||||
Aspect_Touch myClickTouch; //!< single touch position for handling clicks
|
||||
OSD_Timer myDoubleTapTimer; //!< timer for handling double tap
|
||||
float myDevicePixelRatio; //!< device pixel ratio for handling high DPI displays
|
||||
unsigned int myUpdateRequests; //!< counter for unhandled update requests
|
||||
|
||||
};
|
||||
|
||||
#endif // _WasmOcctView_HeaderFile
|
264
samples/webgl/WasmVKeys.h
Normal file
264
samples/webgl/WasmVKeys.h
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of the examples of the Open CASCADE Technology software library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
#ifndef _WasmVKeys_HeaderFile
|
||||
#define _WasmVKeys_HeaderFile
|
||||
|
||||
#include <Aspect_VKey.hxx>
|
||||
|
||||
#include <emscripten/key_codes.h>
|
||||
|
||||
//! Convert Emscripten mouse buttons into Aspect_VKeyMouse.
|
||||
inline Aspect_VKeyMouse WasmVKeys_MouseButtonsFromNative (unsigned short theButtons)
|
||||
{
|
||||
Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
|
||||
if ((theButtons & 0x1) != 0)
|
||||
{
|
||||
aButtons |= Aspect_VKeyMouse_LeftButton;
|
||||
}
|
||||
if ((theButtons & 0x2) != 0)
|
||||
{
|
||||
aButtons |= Aspect_VKeyMouse_RightButton;
|
||||
}
|
||||
if ((theButtons & 0x4) != 0)
|
||||
{
|
||||
aButtons |= Aspect_VKeyMouse_MiddleButton;
|
||||
}
|
||||
return aButtons;
|
||||
}
|
||||
|
||||
//! Convert DOM virtual key into Aspect_VKey.
|
||||
inline Aspect_VKey WasmVKeys_VirtualKeyFromNative (Standard_Integer theKey)
|
||||
{
|
||||
if (theKey >= DOM_VK_0
|
||||
&& theKey <= DOM_VK_9)
|
||||
{
|
||||
// numpad keys
|
||||
return Aspect_VKey((theKey - DOM_VK_0) + Aspect_VKey_0);
|
||||
}
|
||||
if (theKey >= DOM_VK_A
|
||||
&& theKey <= DOM_VK_Z)
|
||||
{
|
||||
// main latin alphabet keys
|
||||
return Aspect_VKey((theKey - DOM_VK_A) + Aspect_VKey_A);
|
||||
}
|
||||
if (theKey >= DOM_VK_F1
|
||||
&& theKey <= DOM_VK_F24)
|
||||
{
|
||||
// special keys
|
||||
if (theKey <= DOM_VK_F12)
|
||||
{
|
||||
return Aspect_VKey((theKey - DOM_VK_F1) + Aspect_VKey_F1);
|
||||
}
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
}
|
||||
if (theKey >= DOM_VK_NUMPAD0
|
||||
&& theKey <= DOM_VK_NUMPAD9)
|
||||
{
|
||||
// numpad keys
|
||||
return Aspect_VKey((theKey - DOM_VK_NUMPAD0) + Aspect_VKey_Numpad0);
|
||||
}
|
||||
|
||||
switch (theKey)
|
||||
{
|
||||
case DOM_VK_CANCEL:
|
||||
case DOM_VK_HELP:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_BACK_SPACE:
|
||||
return Aspect_VKey_Backspace;
|
||||
case DOM_VK_TAB:
|
||||
return Aspect_VKey_Tab;
|
||||
case DOM_VK_CLEAR:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_RETURN:
|
||||
case DOM_VK_ENTER:
|
||||
return Aspect_VKey_Enter;
|
||||
case DOM_VK_SHIFT:
|
||||
return Aspect_VKey_Shift;
|
||||
case DOM_VK_CONTROL:
|
||||
return Aspect_VKey_Control;
|
||||
case DOM_VK_ALT:
|
||||
return Aspect_VKey_Alt;
|
||||
case DOM_VK_PAUSE:
|
||||
case DOM_VK_CAPS_LOCK:
|
||||
case DOM_VK_KANA:
|
||||
//case DOM_VK_HANGUL:
|
||||
case DOM_VK_EISU:
|
||||
case DOM_VK_JUNJA:
|
||||
case DOM_VK_FINAL:
|
||||
case DOM_VK_HANJA:
|
||||
//case DOM_VK_KANJI:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_ESCAPE:
|
||||
return Aspect_VKey_Escape;
|
||||
case DOM_VK_CONVERT:
|
||||
case DOM_VK_NONCONVERT:
|
||||
case DOM_VK_ACCEPT:
|
||||
case DOM_VK_MODECHANGE:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_SPACE:
|
||||
return Aspect_VKey_Space;
|
||||
case DOM_VK_PAGE_UP:
|
||||
return Aspect_VKey_PageUp;
|
||||
case DOM_VK_PAGE_DOWN:
|
||||
return Aspect_VKey_PageDown;
|
||||
case DOM_VK_END:
|
||||
return Aspect_VKey_End;
|
||||
case DOM_VK_HOME:
|
||||
return Aspect_VKey_Home;
|
||||
case DOM_VK_LEFT:
|
||||
return Aspect_VKey_Left;
|
||||
case DOM_VK_UP:
|
||||
return Aspect_VKey_Up;
|
||||
case DOM_VK_RIGHT:
|
||||
return Aspect_VKey_Right;
|
||||
case DOM_VK_DOWN:
|
||||
return Aspect_VKey_Down;
|
||||
case DOM_VK_SELECT:
|
||||
case DOM_VK_PRINT:
|
||||
case DOM_VK_EXECUTE:
|
||||
case DOM_VK_PRINTSCREEN:
|
||||
case DOM_VK_INSERT:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_DELETE:
|
||||
return Aspect_VKey_Delete;
|
||||
case DOM_VK_COLON:
|
||||
return Aspect_VKey_Comma;
|
||||
case DOM_VK_SEMICOLON:
|
||||
return Aspect_VKey_Semicolon;
|
||||
case DOM_VK_LESS_THAN:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_EQUALS:
|
||||
return Aspect_VKey_Equal;
|
||||
case DOM_VK_GREATER_THAN:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_QUESTION_MARK:
|
||||
return Aspect_VKey_Slash;
|
||||
case DOM_VK_AT: // @ key
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_WIN:
|
||||
return Aspect_VKey_Meta;
|
||||
case DOM_VK_CONTEXT_MENU:
|
||||
case DOM_VK_SLEEP:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_MULTIPLY:
|
||||
return Aspect_VKey_NumpadMultiply;
|
||||
case DOM_VK_ADD:
|
||||
return Aspect_VKey_NumpadAdd;
|
||||
case DOM_VK_SEPARATOR:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_SUBTRACT:
|
||||
return Aspect_VKey_NumpadSubtract;
|
||||
case DOM_VK_DECIMAL:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_DIVIDE:
|
||||
return Aspect_VKey_NumpadDivide;
|
||||
case DOM_VK_NUM_LOCK:
|
||||
return Aspect_VKey_Numlock;
|
||||
case DOM_VK_SCROLL_LOCK:
|
||||
return Aspect_VKey_Scroll;
|
||||
case DOM_VK_WIN_OEM_FJ_JISHO:
|
||||
case DOM_VK_WIN_OEM_FJ_MASSHOU:
|
||||
case DOM_VK_WIN_OEM_FJ_TOUROKU:
|
||||
case DOM_VK_WIN_OEM_FJ_LOYA:
|
||||
case DOM_VK_WIN_OEM_FJ_ROYA:
|
||||
case DOM_VK_CIRCUMFLEX:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_EXCLAMATION:
|
||||
case DOM_VK_DOUBLE_QUOTE:
|
||||
//case DOM_VK_HASH:
|
||||
case DOM_VK_DOLLAR:
|
||||
case DOM_VK_PERCENT:
|
||||
case DOM_VK_AMPERSAND:
|
||||
case DOM_VK_UNDERSCORE:
|
||||
case DOM_VK_OPEN_PAREN:
|
||||
case DOM_VK_CLOSE_PAREN:
|
||||
case DOM_VK_ASTERISK:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_PLUS:
|
||||
return Aspect_VKey_Plus;
|
||||
case DOM_VK_PIPE:
|
||||
case DOM_VK_HYPHEN_MINUS:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_OPEN_CURLY_BRACKET:
|
||||
return Aspect_VKey_BracketLeft;
|
||||
case DOM_VK_CLOSE_CURLY_BRACKET:
|
||||
return Aspect_VKey_BracketRight;
|
||||
case DOM_VK_TILDE:
|
||||
return Aspect_VKey_Tilde;
|
||||
case DOM_VK_VOLUME_MUTE:
|
||||
return Aspect_VKey_VolumeMute;
|
||||
case DOM_VK_VOLUME_DOWN:
|
||||
return Aspect_VKey_VolumeDown;
|
||||
case DOM_VK_VOLUME_UP:
|
||||
return Aspect_VKey_VolumeUp;
|
||||
case DOM_VK_COMMA:
|
||||
return Aspect_VKey_Comma;
|
||||
case DOM_VK_PERIOD:
|
||||
return Aspect_VKey_Period;
|
||||
case DOM_VK_SLASH:
|
||||
return Aspect_VKey_Slash;
|
||||
case DOM_VK_BACK_QUOTE:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_OPEN_BRACKET:
|
||||
return Aspect_VKey_BracketLeft;
|
||||
case DOM_VK_BACK_SLASH:
|
||||
return Aspect_VKey_Backslash;
|
||||
case DOM_VK_CLOSE_BRACKET:
|
||||
return Aspect_VKey_BracketRight;
|
||||
case DOM_VK_QUOTE:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_META:
|
||||
return Aspect_VKey_Meta;
|
||||
case DOM_VK_ALTGR:
|
||||
return Aspect_VKey_Alt;
|
||||
case DOM_VK_WIN_ICO_HELP:
|
||||
case DOM_VK_WIN_ICO_00:
|
||||
case DOM_VK_WIN_ICO_CLEAR:
|
||||
case DOM_VK_WIN_OEM_RESET:
|
||||
case DOM_VK_WIN_OEM_JUMP:
|
||||
case DOM_VK_WIN_OEM_PA1:
|
||||
case DOM_VK_WIN_OEM_PA2:
|
||||
case DOM_VK_WIN_OEM_PA3:
|
||||
case DOM_VK_WIN_OEM_WSCTRL:
|
||||
case DOM_VK_WIN_OEM_CUSEL:
|
||||
case DOM_VK_WIN_OEM_ATTN:
|
||||
case DOM_VK_WIN_OEM_FINISH:
|
||||
case DOM_VK_WIN_OEM_COPY:
|
||||
case DOM_VK_WIN_OEM_AUTO:
|
||||
case DOM_VK_WIN_OEM_ENLW:
|
||||
case DOM_VK_WIN_OEM_BACKTAB:
|
||||
case DOM_VK_ATTN:
|
||||
case DOM_VK_CRSEL:
|
||||
case DOM_VK_EXSEL:
|
||||
case DOM_VK_EREOF:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
case DOM_VK_PLAY:
|
||||
return Aspect_VKey_MediaPlayPause;
|
||||
case DOM_VK_ZOOM:
|
||||
case DOM_VK_PA1:
|
||||
case DOM_VK_WIN_OEM_CLEAR:
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
}
|
||||
return Aspect_VKey_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif // _WasmVKeys_HeaderFile
|
66
samples/webgl/main.cpp
Normal file
66
samples/webgl/main.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "WasmOcctView.h"
|
||||
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <OSD_MemInfo.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
|
||||
#include <AIS_Shape.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <Standard_ArrayStreamBuffer.hxx>
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
//! Global viewer instance.
|
||||
static WasmOcctView aViewer;
|
||||
|
||||
//! File data read event.
|
||||
extern "C" void onFileDataRead (void* theOpaque, void* theBuffer, int theDataLen)
|
||||
{
|
||||
const char* aName = theOpaque != NULL ? (const char* )theOpaque : "";
|
||||
{
|
||||
AIS_ListOfInteractive aShapes;
|
||||
aViewer.Context()->DisplayedObjects (AIS_KOI_Shape, -1, aShapes);
|
||||
for (AIS_ListOfInteractive::Iterator aShapeIter (aShapes); aShapeIter.More(); aShapeIter.Next())
|
||||
{
|
||||
aViewer.Context()->Remove (aShapeIter.Value(), false);
|
||||
}
|
||||
}
|
||||
|
||||
Standard_ArrayStreamBuffer aStreamBuffer ((const char* )theBuffer, theDataLen);
|
||||
std::istream aStream (&aStreamBuffer);
|
||||
TopoDS_Shape aShape;
|
||||
BRep_Builder aBuilder;
|
||||
BRepTools::Read (aShape, aStream, aBuilder);
|
||||
|
||||
Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape);
|
||||
aShapePrs->SetMaterial (Graphic3d_NOM_SILVER);
|
||||
aViewer.Context()->Display (aShapePrs, AIS_Shaded, 0, false);
|
||||
aViewer.View()->FitAll (0.01, false);
|
||||
aViewer.View()->Redraw();
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Loaded file ") + aName, Message_Info);
|
||||
Message::DefaultMessenger()->Send (OSD_MemInfo::PrintInfo(), Message_Trace);
|
||||
}
|
||||
|
||||
//! File read error event.
|
||||
static void onFileReadFailed (void* theOpaque)
|
||||
{
|
||||
const char* aName = (const char* )theOpaque;
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Error: unable to load file ") + aName, Message_Fail);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Message::DefaultMessenger()->Printers().First()->SetTraceLevel (Message_Trace);
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("NbLogicalProcessors: ") + OSD_Parallel::NbLogicalProcessors(), Message_Trace);
|
||||
aViewer.run();
|
||||
Message::DefaultMessenger()->Send (OSD_MemInfo::PrintInfo(), Message_Trace);
|
||||
|
||||
// load some file
|
||||
emscripten_async_wget_data ("samples/Ball.brep", (void* )"samples/Ball.brep", onFileDataRead, onFileReadFailed);
|
||||
return 0;
|
||||
}
|
133
samples/webgl/occt-webgl-sample.html
Normal file
133
samples/webgl/occt-webgl-sample.html
Normal file
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang=en-us>
|
||||
<head>
|
||||
<meta charset=utf-8><meta content="text/html; charset=utf-8" http-equiv=Content-Type>
|
||||
<link rel="shortcut icon" href="lamp.ico" type="image/x-icon" />
|
||||
<title>OCCT WebGL Viewer Sample</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>OCCT WebGL Viewer Sample</h2>
|
||||
<div>
|
||||
<canvas id=canvas oncontextmenu=event.preventDefault() tabindex=-1 style="border:0 none;background-color:#000" width="409" height="409"></canvas>
|
||||
<img id=occlogo src="OCC_logo.png" style="position: absolute; left: 20px; top: 0px; z-index: 2;" />
|
||||
</div>
|
||||
|
||||
<div><label for="fileInput">Choose BREP file to upload: </label><input type="file" id="fileInput" accept=".brep"></div>
|
||||
<h4>Console output:</h4>
|
||||
<p id="output"></p>
|
||||
<script>
|
||||
//! Resize canvas to fit into window.
|
||||
function updateCanvasSize()
|
||||
{
|
||||
// size of canvas in logical (density-independent) units
|
||||
var aSizeX = Math.min (window.innerWidth, window.screen.availWidth);
|
||||
var aSizeY = Math.min (window.innerHeight, window.screen.availHeight);
|
||||
aSizeX = Math.max (300, aSizeX - 30);
|
||||
aSizeY = Math.max (300, aSizeY / 2);
|
||||
canvas.style.width = aSizeX + "px";
|
||||
canvas.style.height = aSizeY + "px";
|
||||
|
||||
// drawing buffer size (aka backing store)
|
||||
var aDevicePixelRatio = window.devicePixelRatio || 1;
|
||||
canvas.width = aSizeX * aDevicePixelRatio;
|
||||
canvas.height = aSizeY * aDevicePixelRatio;
|
||||
|
||||
occlogo.style.top = (aSizeY - 30) + "px";
|
||||
}
|
||||
window.onresize = updateCanvasSize;
|
||||
updateCanvasSize();
|
||||
|
||||
//! Check browser support.
|
||||
function isWasmSupported()
|
||||
{
|
||||
try {
|
||||
if (typeof WebAssembly === "object"
|
||||
&& typeof WebAssembly.instantiate === "function") {
|
||||
const aDummyModule = new WebAssembly.Module (Uint8Array.of (0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
|
||||
if (aDummyModule instanceof WebAssembly.Module)
|
||||
{
|
||||
return new WebAssembly.Instance(aDummyModule) instanceof WebAssembly.Instance;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
return false;
|
||||
}
|
||||
if (!isWasmSupported())
|
||||
{
|
||||
var anElement = document.getElementById('output');
|
||||
anElement.innerHTML += "Browser is too old - WebAssembly support is missing!<br>Please check updates or install a modern browser.<br>";
|
||||
}
|
||||
|
||||
//! Define OCCT WebGL Viewer module.
|
||||
var Module =
|
||||
{
|
||||
print: (function() {
|
||||
var anElement = document.getElementById('output');
|
||||
return function(theText) { anElement.innerHTML += theText + "<br>"; };
|
||||
})(),
|
||||
printErr: function(theText) {
|
||||
//var anElement = document.getElementById('output');
|
||||
//anElement.innerHTML += theText + "<br>";
|
||||
},
|
||||
canvas: (function() {
|
||||
var aCanvas = document.getElementById('canvas');
|
||||
return aCanvas;
|
||||
})()
|
||||
};
|
||||
|
||||
//! Handle file uploading.
|
||||
fileInput.onchange = function()
|
||||
{
|
||||
if (fileInput.files.length == 0) { return; }
|
||||
// Warning! Entire file is pre-loaded into memory.
|
||||
var aFile = fileInput.files[0];
|
||||
var aReader = new FileReader();
|
||||
aReader.onload = function()
|
||||
{
|
||||
var aDataArray = new Uint8Array (aReader.result);
|
||||
var aNameArray = new Uint8Array (toUtf8Array (aFile.name));
|
||||
const aDataBuffer = Module._malloc(aDataArray.length);
|
||||
const aNameBuffer = Module._malloc(aNameArray.length);
|
||||
Module.HEAPU8.set(aNameArray, aNameBuffer);
|
||||
Module.HEAPU8.set(aDataArray, aDataBuffer);
|
||||
Module.ccall('onFileDataRead', null, ['number', 'number', 'number'], [aNameBuffer, aDataBuffer, aDataArray.length]);
|
||||
Module._free(aDataBuffer);
|
||||
Module._free(aNameBuffer);
|
||||
fileInput.value = '';
|
||||
};
|
||||
aReader.readAsArrayBuffer(aFile);
|
||||
};
|
||||
|
||||
//! Convert string into UTF-8 array.
|
||||
function toUtf8Array (theText)
|
||||
{
|
||||
var aRes = [];
|
||||
for (var aCharIter = 0; aCharIter < theText.length; ++aCharIter)
|
||||
{
|
||||
var aCharCode = theText.charCodeAt (aCharIter);
|
||||
if (aCharCode < 0x80)
|
||||
{
|
||||
aRes.push (aCharCode);
|
||||
}
|
||||
else if (aCharCode < 0x800)
|
||||
{
|
||||
aRes.push (0xc0 | (aCharCode >> 6), 0x80 | (aCharCode & 0x3f));
|
||||
}
|
||||
else if (aCharCode < 0xd800 || aCharCode >= 0xe000)
|
||||
{
|
||||
aRes.push (0xe0 | (aCharCode >> 12), 0x80 | ((aCharCode>>6) & 0x3f), 0x80 | (aCharCode & 0x3f));
|
||||
}
|
||||
else
|
||||
{
|
||||
++aCharIter;
|
||||
aCharCode = 0x10000 + (((aCharCode & 0x3ff)<<10) | (theText.charCodeAt (aCharIter) & 0x3ff));
|
||||
aRes.push(0xf0 | (aCharCode >>18), 0x80 | ((aCharCode>>12) & 0x3f), 0x80 | ((aCharCode>>6) & 0x3f), 0x80 | (aCharCode & 0x3f));
|
||||
}
|
||||
}
|
||||
return aRes;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="occt-webgl-sample.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
@@ -415,11 +415,6 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
|
||||
//=======================================================================
|
||||
Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const
|
||||
{
|
||||
{
|
||||
Handle(V3d_Viewer) aViewer = GetContext()->CurrentViewer();
|
||||
aViewer->InitActiveViews(); // for AIS_ColorScale::TextSize()
|
||||
}
|
||||
|
||||
Standard_Integer aWidthMax = 0;
|
||||
for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next())
|
||||
{
|
||||
|
@@ -26,6 +26,7 @@ public:
|
||||
//! Default constructor.
|
||||
AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink)
|
||||
: myIsHidden (false),
|
||||
myHasOwnMaterial(false),
|
||||
myHasOwnColor (false),
|
||||
myHasOwnTransp(false),
|
||||
myHasOwnWidth (false)
|
||||
@@ -36,6 +37,10 @@ public:
|
||||
bool IsHidden() const { return myIsHidden; }
|
||||
void SetHidden (const bool theToHide) { myIsHidden = theToHide;}
|
||||
|
||||
bool HasOwnMaterial() const { return myHasOwnMaterial; }
|
||||
void UnsetOwnMaterial() { myHasOwnMaterial = false; }
|
||||
void SetOwnMaterial() { myHasOwnMaterial = true; }
|
||||
|
||||
bool HasOwnColor() const { return myHasOwnColor; }
|
||||
void UnsetOwnColor() { myHasOwnColor = false; }
|
||||
void SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = true; }
|
||||
@@ -51,6 +56,7 @@ public:
|
||||
public: //! @name list of overridden properties
|
||||
|
||||
bool myIsHidden;
|
||||
bool myHasOwnMaterial;
|
||||
bool myHasOwnColor;
|
||||
bool myHasOwnTransp;
|
||||
bool myHasOwnWidth;
|
||||
|
@@ -333,7 +333,11 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
|
||||
for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
|
||||
{
|
||||
const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
|
||||
//if (aDrawer->HasOwnMaterial()) continue;
|
||||
if (aDrawer->HasOwnMaterial())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aDrawer->HasOwnShadingAspect())
|
||||
{
|
||||
setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), aDrawer->HasOwnTransparency());
|
||||
|
@@ -79,6 +79,12 @@ void AIS_ConnectedInteractive::connect (const Handle(AIS_InteractiveObject)& the
|
||||
|
||||
if (!myReference.IsNull())
|
||||
{
|
||||
if (myReference->HasInteractiveContext()
|
||||
&& myReference->GetContext()->DisplayStatus (myReference) != AIS_DS_None)
|
||||
{
|
||||
myReference.Nullify();
|
||||
throw Standard_ProgramError("AIS_ConnectedInteractive::Connect() - connected object should NOT be displayed in context");
|
||||
}
|
||||
myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
|
||||
}
|
||||
setLocalTransformation (theLocation);
|
||||
|
@@ -17,9 +17,12 @@
|
||||
#ifndef _AIS_DisplayStatus_HeaderFile
|
||||
#define _AIS_DisplayStatus_HeaderFile
|
||||
|
||||
#include <PrsMgr_DisplayStatus.hxx>
|
||||
|
||||
//! To give the display status of an Interactive Object.
|
||||
typedef PrsMgr_DisplayStatus AIS_DisplayStatus;
|
||||
enum AIS_DisplayStatus
|
||||
{
|
||||
AIS_DS_Displayed, //!< the Interactive Object is displayed in the main viewer
|
||||
AIS_DS_Erased, //!< the Interactive Object is hidden in main viewer
|
||||
AIS_DS_None //!< the Interactive Object is nowhere displayed
|
||||
};
|
||||
|
||||
#endif // _AIS_DisplayStatus_HeaderFile
|
||||
|
@@ -23,6 +23,7 @@
|
||||
IMPLEMENT_STANDARD_RTTIEXT(AIS_GlobalStatus, Standard_Transient)
|
||||
|
||||
AIS_GlobalStatus::AIS_GlobalStatus():
|
||||
myStatus(AIS_DS_None),
|
||||
myDispMode(AIS_WireFrame),
|
||||
myLayerIndex(0),
|
||||
myIsHilit(Standard_False),
|
||||
@@ -30,15 +31,18 @@ mySubInt(Standard_False)
|
||||
{
|
||||
}
|
||||
|
||||
AIS_GlobalStatus::AIS_GlobalStatus (const Standard_Integer theDMode,
|
||||
const Standard_Integer theSMode,
|
||||
const Standard_Integer theLayer):
|
||||
myDispMode (theDMode),
|
||||
myLayerIndex (theLayer),
|
||||
myIsHilit (Standard_False),
|
||||
mySubInt (Standard_False)
|
||||
AIS_GlobalStatus::AIS_GlobalStatus(const AIS_DisplayStatus DS,
|
||||
const Standard_Integer DMode,
|
||||
const Standard_Integer SMode,
|
||||
const Standard_Boolean /*ishilighted*/,
|
||||
const Standard_Integer Layer):
|
||||
myStatus(DS),
|
||||
myDispMode(DMode),
|
||||
myLayerIndex(Layer),
|
||||
myIsHilit(Standard_False),
|
||||
mySubInt(Standard_False)
|
||||
{
|
||||
mySelModes.Append (theSMode);
|
||||
mySelModes.Append(SMode);
|
||||
}
|
||||
|
||||
void AIS_GlobalStatus::RemoveSelectionMode(const Standard_Integer aMode)
|
||||
|
@@ -43,9 +43,9 @@ public:
|
||||
|
||||
Standard_EXPORT AIS_GlobalStatus();
|
||||
|
||||
Standard_EXPORT AIS_GlobalStatus (const Standard_Integer theDispMode,
|
||||
const Standard_Integer theSelMode,
|
||||
const Standard_Integer theLayerIndex = 0);
|
||||
Standard_EXPORT AIS_GlobalStatus(const AIS_DisplayStatus aStat, const Standard_Integer aDispMode, const Standard_Integer aSelMode, const Standard_Boolean ishilighted = Standard_False, const Standard_Integer aLayerIndex = 0);
|
||||
|
||||
void SetGraphicStatus (const AIS_DisplayStatus theStatus) { myStatus = theStatus; }
|
||||
|
||||
void AddSelectionMode (const Standard_Integer theMode) { if (!IsSModeIn (theMode)) mySelModes.Append (theMode); }
|
||||
|
||||
@@ -74,7 +74,9 @@ public:
|
||||
Standard_EXPORT void RemoveSelectionMode (const Standard_Integer aMode);
|
||||
|
||||
Standard_EXPORT void ClearSelectionModes();
|
||||
|
||||
|
||||
AIS_DisplayStatus GraphicStatus() const { return myStatus; }
|
||||
|
||||
//! keeps the active selection modes of the object
|
||||
//! in the main viewer.
|
||||
const TColStd_ListOfInteger& SelectionModes() const { return mySelModes; }
|
||||
@@ -93,6 +95,7 @@ private:
|
||||
|
||||
TColStd_ListOfInteger mySelModes;
|
||||
Handle(Prs3d_Drawer) myHiStyle;
|
||||
AIS_DisplayStatus myStatus;
|
||||
Standard_Integer myDispMode;
|
||||
Standard_Integer myLayerIndex;
|
||||
Standard_Boolean myIsHilit;
|
||||
|
@@ -229,7 +229,7 @@ void AIS_InteractiveContext::DisplayedObjects (AIS_ListOfInteractive& theListOfI
|
||||
{
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
if (anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (anObjIter.Value()->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
theListOfIO.Append (anObjIter.Key());
|
||||
}
|
||||
@@ -244,7 +244,7 @@ void AIS_InteractiveContext::DisplayedObjects (const AIS_KindOfInteractive theKi
|
||||
const Standard_Integer theSign,
|
||||
AIS_ListOfInteractive& theListOfIO) const
|
||||
{
|
||||
ObjectsByDisplayStatus (theKind, theSign, PrsMgr_DisplayStatus_Displayed, theListOfIO);
|
||||
ObjectsByDisplayStatus (theKind, theSign, AIS_DS_Displayed, theListOfIO);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -253,7 +253,7 @@ void AIS_InteractiveContext::DisplayedObjects (const AIS_KindOfInteractive theKi
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::ErasedObjects (AIS_ListOfInteractive& theListOfIO) const
|
||||
{
|
||||
ObjectsByDisplayStatus (PrsMgr_DisplayStatus_Erased, theListOfIO);
|
||||
ObjectsByDisplayStatus (AIS_DS_Erased, theListOfIO);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -264,19 +264,19 @@ void AIS_InteractiveContext::ErasedObjects (const AIS_KindOfInteractive theKind,
|
||||
const Standard_Integer theSign,
|
||||
AIS_ListOfInteractive& theListOfIO) const
|
||||
{
|
||||
ObjectsByDisplayStatus (theKind, theSign, PrsMgr_DisplayStatus_Erased, theListOfIO);
|
||||
ObjectsByDisplayStatus (theKind, theSign, AIS_DS_Erased, theListOfIO);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ObjectsByDisplayStatus
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::ObjectsByDisplayStatus (const PrsMgr_DisplayStatus theStatus,
|
||||
void AIS_InteractiveContext::ObjectsByDisplayStatus (const AIS_DisplayStatus theStatus,
|
||||
AIS_ListOfInteractive& theListOfIO) const
|
||||
{
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
if (anObjIter.Key()->DisplayStatus() == theStatus)
|
||||
if (anObjIter.Value()->GraphicStatus() == theStatus)
|
||||
{
|
||||
theListOfIO.Append (anObjIter.Key());
|
||||
}
|
||||
@@ -289,13 +289,13 @@ void AIS_InteractiveContext::ObjectsByDisplayStatus (const PrsMgr_DisplayStatus
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::ObjectsByDisplayStatus (const AIS_KindOfInteractive theKind,
|
||||
const Standard_Integer theSign,
|
||||
const PrsMgr_DisplayStatus theStatus,
|
||||
const AIS_DisplayStatus theStatus,
|
||||
AIS_ListOfInteractive& theListOfIO) const
|
||||
{
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
if (theStatus != PrsMgr_DisplayStatus_None
|
||||
&& anObjIter.Key()->DisplayStatus() != theStatus)
|
||||
if (theStatus != AIS_DS_None
|
||||
&& anObjIter.Value()->GraphicStatus() != theStatus)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -352,14 +352,14 @@ void AIS_InteractiveContext::ObjectsInside (AIS_ListOfInteractive& theListO
|
||||
void AIS_InteractiveContext::ObjectsForView (AIS_ListOfInteractive& theListOfIO,
|
||||
const Handle(V3d_View)& theView,
|
||||
const Standard_Boolean theIsVisibleInView,
|
||||
const PrsMgr_DisplayStatus theStatus) const
|
||||
const AIS_DisplayStatus theStatus) const
|
||||
{
|
||||
Handle(Graphic3d_CView) aViewImpl = theView->View();
|
||||
const Standard_Integer aViewId = aViewImpl->Identification();
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
if (theStatus != PrsMgr_DisplayStatus_None
|
||||
&& anObjIter.Key()->DisplayStatus() != theStatus)
|
||||
if (theStatus != AIS_DS_None
|
||||
&& anObjIter.Value()->GraphicStatus() != theStatus)
|
||||
{
|
||||
theListOfIO.Append (anObjIter.Key());
|
||||
continue;
|
||||
@@ -426,14 +426,14 @@ void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIO
|
||||
const Standard_Integer theDispMode,
|
||||
const Standard_Integer theSelectionMode,
|
||||
const Standard_Boolean theToUpdateViewer,
|
||||
const PrsMgr_DisplayStatus theDispStatus)
|
||||
const AIS_DisplayStatus theDispStatus)
|
||||
{
|
||||
if (theIObj.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (theDispStatus == PrsMgr_DisplayStatus_Erased)
|
||||
if (theDispStatus == AIS_DS_Erased)
|
||||
{
|
||||
Erase (theIObj, theToUpdateViewer);
|
||||
Load (theIObj, theSelectionMode);
|
||||
@@ -447,7 +447,7 @@ void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIO
|
||||
setContextToObject (theIObj);
|
||||
if (!myObjects.IsBound (theIObj))
|
||||
{
|
||||
setObjectStatus (theIObj, PrsMgr_DisplayStatus_Displayed, theDispMode, theSelectionMode);
|
||||
setObjectStatus (theIObj, AIS_DS_Displayed, theDispMode, theSelectionMode);
|
||||
myMainVwr->StructureManager()->RegisterObject (theIObj);
|
||||
myMainPM->Display(theIObj, theDispMode);
|
||||
if (theSelectionMode != -1)
|
||||
@@ -479,8 +479,8 @@ void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIO
|
||||
|
||||
aStatus->SetDisplayMode (theDispMode);
|
||||
|
||||
theIObj->SetDisplayStatus (PrsMgr_DisplayStatus_Displayed);
|
||||
myMainPM->Display (theIObj, theDispMode);
|
||||
aStatus->SetGraphicStatus (AIS_DS_Displayed);
|
||||
if (aStatus->IsHilighted())
|
||||
{
|
||||
highlightGlobal (theIObj, aStatus->HilightStyle(), theDispMode);
|
||||
@@ -524,7 +524,7 @@ void AIS_InteractiveContext::Load (const Handle(AIS_InteractiveObject)& theIObj,
|
||||
{
|
||||
Standard_Integer aDispMode, aHiMod, aSelModeDef;
|
||||
GetDefModes (theIObj, aDispMode, aHiMod, aSelModeDef);
|
||||
setObjectStatus (theIObj, PrsMgr_DisplayStatus_Erased, aDispMode, theSelMode != -1 ? theSelMode : aSelModeDef);
|
||||
setObjectStatus (theIObj, AIS_DS_Erased, aDispMode, theSelMode != -1 ? theSelMode : aSelModeDef);
|
||||
myMainVwr->StructureManager()->RegisterObject (theIObj);
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ void AIS_InteractiveContext::EraseAll (const Standard_Boolean theToUpdateViewer)
|
||||
{
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
if (anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (anObjIter.Value()->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
Erase (anObjIter.Key(), Standard_False);
|
||||
}
|
||||
@@ -588,8 +588,8 @@ void AIS_InteractiveContext::DisplayAll (const Standard_Boolean theToUpdateViewe
|
||||
{
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
|
||||
{
|
||||
const PrsMgr_DisplayStatus aStatus = anObjIter.Key()->DisplayStatus();
|
||||
if (aStatus == PrsMgr_DisplayStatus_Erased)
|
||||
const AIS_DisplayStatus aStatus = anObjIter.Value()->GraphicStatus();
|
||||
if (aStatus == AIS_DS_Erased)
|
||||
{
|
||||
Display (anObjIter.Key(), Standard_False);
|
||||
}
|
||||
@@ -643,14 +643,14 @@ void AIS_InteractiveContext::EraseSelected (const Standard_Boolean theToUpdateVi
|
||||
//function : DisplayStatus
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
PrsMgr_DisplayStatus AIS_InteractiveContext::DisplayStatus (const Handle(AIS_InteractiveObject)& theIObj) const
|
||||
AIS_DisplayStatus AIS_InteractiveContext::DisplayStatus (const Handle(AIS_InteractiveObject)& theIObj) const
|
||||
{
|
||||
if (theIObj.IsNull())
|
||||
{
|
||||
return PrsMgr_DisplayStatus_None;
|
||||
return AIS_DS_None;
|
||||
}
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
return aStatus != NULL ? theIObj->DisplayStatus() : PrsMgr_DisplayStatus_None;
|
||||
return aStatus != NULL ? (*aStatus)->GraphicStatus() : AIS_DS_None;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -713,7 +713,7 @@ void AIS_InteractiveContext::HilightWithColor(const Handle(AIS_InteractiveObject
|
||||
const Handle(AIS_GlobalStatus)& aStatus = myObjects (theObj);
|
||||
aStatus->SetHilightStatus (Standard_True);
|
||||
|
||||
if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (aStatus->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
highlightGlobal (theObj, theStyle, aStatus->DisplayMode());
|
||||
aStatus->SetHilightStyle (theStyle);
|
||||
@@ -727,26 +727,21 @@ void AIS_InteractiveContext::HilightWithColor(const Handle(AIS_InteractiveObject
|
||||
//function : Unhilight
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::Unhilight (const Handle(AIS_InteractiveObject)& theObj,
|
||||
const Standard_Boolean theToUpdateViewer)
|
||||
void AIS_InteractiveContext::Unhilight(const Handle(AIS_InteractiveObject)& anIObj, const Standard_Boolean updateviewer)
|
||||
{
|
||||
Handle(AIS_GlobalStatus)* aStatus = !theObj.IsNull() ? myObjects.ChangeSeek (theObj) : NULL;
|
||||
if (aStatus == NULL)
|
||||
if(anIObj.IsNull()) return;
|
||||
if(!myObjects.IsBound(anIObj)) return;
|
||||
|
||||
const Handle(AIS_GlobalStatus)& aStatus = myObjects(anIObj);
|
||||
aStatus->SetHilightStatus (Standard_False);
|
||||
aStatus->SetHilightStyle (Handle(Prs3d_Drawer)());
|
||||
|
||||
if (aStatus->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
return;
|
||||
unhighlightGlobal (anIObj);
|
||||
}
|
||||
|
||||
(*aStatus)->SetHilightStatus (Standard_False);
|
||||
(*aStatus)->SetHilightStyle (Handle(Prs3d_Drawer)());
|
||||
if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
{
|
||||
unhighlightGlobal (theObj);
|
||||
}
|
||||
|
||||
if (theToUpdateViewer)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
}
|
||||
if(updateviewer) myMainVwr->Update();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -850,7 +845,7 @@ Standard_Boolean AIS_InteractiveContext::IsDisplayed(const Handle(AIS_Interactiv
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
|
||||
return aStatus != NULL
|
||||
&& theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed;
|
||||
&& (*aStatus)->GraphicStatus() == AIS_DS_Displayed;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -867,7 +862,7 @@ Standard_Boolean AIS_InteractiveContext::IsDisplayed (const Handle(AIS_Interacti
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
return aStatus != NULL
|
||||
&& theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
&& (*aStatus)->GraphicStatus() == AIS_DS_Displayed
|
||||
&& (*aStatus)->DisplayMode() == theMode;
|
||||
}
|
||||
|
||||
@@ -884,8 +879,8 @@ Standard_Integer AIS_InteractiveContext::DisplayPriority (const Handle(AIS_Inter
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
if (aStatus != NULL
|
||||
&& (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
|| theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased))
|
||||
&& ((*aStatus)->GraphicStatus() == AIS_DS_Displayed
|
||||
|| (*aStatus)->GraphicStatus() == AIS_DS_Erased))
|
||||
{
|
||||
Standard_Integer aDispMode = theIObj->HasDisplayMode()
|
||||
? theIObj->DisplayMode()
|
||||
@@ -912,8 +907,8 @@ void AIS_InteractiveContext::SetDisplayPriority (const Handle(AIS_InteractiveObj
|
||||
setContextToObject (theIObj);
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
if (aStatus != NULL
|
||||
&& (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
|| theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased))
|
||||
&& ((*aStatus)->GraphicStatus() == AIS_DS_Displayed
|
||||
|| (*aStatus)->GraphicStatus() == AIS_DS_Erased))
|
||||
{
|
||||
Standard_Integer aDisplayMode = theIObj->HasDisplayMode()
|
||||
? theIObj->DisplayMode()
|
||||
@@ -954,7 +949,7 @@ void AIS_InteractiveContext::Redisplay (const AIS_KindOfInteractive theKOI,
|
||||
}
|
||||
|
||||
Redisplay (anObj, Standard_False);
|
||||
isRedisplayed = anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
isRedisplayed = anObjIter.Value()->GraphicStatus() == AIS_DS_Displayed
|
||||
|| isRedisplayed;
|
||||
}
|
||||
|
||||
@@ -987,7 +982,7 @@ void AIS_InteractiveContext::RecomputePrsOnly (const Handle(AIS_InteractiveObjec
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
if (aStatus != NULL
|
||||
&& theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
&& (*aStatus)->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
}
|
||||
@@ -1007,7 +1002,7 @@ void AIS_InteractiveContext::RecomputeSelectionOnly (const Handle(AIS_Interactiv
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIO);
|
||||
if (aStatus == NULL
|
||||
|| theIO->DisplayStatus() != PrsMgr_DisplayStatus_Displayed)
|
||||
|| (*aStatus)->GraphicStatus() != AIS_DS_Displayed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1040,7 +1035,7 @@ void AIS_InteractiveContext::Update (const Handle(AIS_InteractiveObject)& theIOb
|
||||
{
|
||||
const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
|
||||
if (aStatus != NULL
|
||||
&& theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
&& (*aStatus)->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
}
|
||||
@@ -1242,7 +1237,7 @@ void AIS_InteractiveContext::SetDisplayMode(const Standard_Integer theMode,
|
||||
Handle(AIS_GlobalStatus) aStatus = anObjIter.Value();
|
||||
aStatus->SetDisplayMode (theMode);
|
||||
|
||||
if (anObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (aStatus->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
myMainPM->Display (anObj, theMode);
|
||||
if (!myLastPicked.IsNull() && myLastPicked->IsSameSelectable (anObj))
|
||||
@@ -1286,7 +1281,7 @@ void AIS_InteractiveContext::SetDisplayMode (const Handle(AIS_InteractiveObject)
|
||||
}
|
||||
|
||||
Handle(AIS_GlobalStatus) aStatus = myObjects (theIObj);
|
||||
if (theIObj->DisplayStatus() != PrsMgr_DisplayStatus_Displayed)
|
||||
if (aStatus->GraphicStatus() != AIS_DS_Displayed)
|
||||
{
|
||||
aStatus->SetDisplayMode (theMode);
|
||||
theIObj->SetDisplayMode (theMode);
|
||||
@@ -1351,7 +1346,7 @@ void AIS_InteractiveContext::UnsetDisplayMode (const Handle(AIS_InteractiveObjec
|
||||
const Handle(AIS_GlobalStatus)& aStatus = myObjects (theIObj);
|
||||
aStatus->SetDisplayMode (myDefaultDrawer->DisplayMode());
|
||||
|
||||
if (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (aStatus->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
if (myMainPM->IsHighlighted (theIObj, anOldMode))
|
||||
{
|
||||
@@ -1901,14 +1896,14 @@ void AIS_InteractiveContext::Status (const Handle(AIS_InteractiveObject)& theIOb
|
||||
theStatus += "\t ____________________________________________";
|
||||
theStatus += "\t| Known at Neutral Point:\n\tDisplayStatus:";
|
||||
const Handle(AIS_GlobalStatus)& aStatus = myObjects (theIObj);
|
||||
switch (theIObj->DisplayStatus())
|
||||
switch (aStatus->GraphicStatus())
|
||||
{
|
||||
case PrsMgr_DisplayStatus_Displayed:
|
||||
case AIS_DS_Displayed:
|
||||
{
|
||||
theStatus += "\t| -->Displayed\n";
|
||||
break;
|
||||
}
|
||||
case PrsMgr_DisplayStatus_Erased:
|
||||
case AIS_DS_Erased:
|
||||
{
|
||||
theStatus += "\t| -->Erased\n";
|
||||
break;
|
||||
@@ -1967,7 +1962,7 @@ void AIS_InteractiveContext::EraseGlobal (const Handle(AIS_InteractiveObject)& t
|
||||
Handle(AIS_GlobalStatus) aStatus;
|
||||
if (theIObj.IsNull()
|
||||
|| !myObjects.Find (theIObj, aStatus)
|
||||
|| theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased)
|
||||
|| aStatus->GraphicStatus() == AIS_DS_Erased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1996,7 +1991,7 @@ void AIS_InteractiveContext::EraseGlobal (const Handle(AIS_InteractiveObject)& t
|
||||
mgrSelector->Deactivate (theIObj, aSelModeIter.Value());
|
||||
}
|
||||
aStatus->ClearSelectionModes();
|
||||
theIObj->SetDisplayStatus (PrsMgr_DisplayStatus_Erased);
|
||||
aStatus->SetGraphicStatus (AIS_DS_Erased);
|
||||
|
||||
if (theToUpdateviewer)
|
||||
{
|
||||
@@ -2082,7 +2077,7 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t
|
||||
const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
|
||||
mgrSelector->Remove (anObj);
|
||||
|
||||
setObjectStatus (theIObj, PrsMgr_DisplayStatus_None, -1, -1);
|
||||
setObjectStatus (theIObj, AIS_DS_None, -1, -1);
|
||||
myMainVwr->StructureManager()->UnregisterObject (theIObj);
|
||||
|
||||
for (V3d_ListOfViewIterator aDefViewIter (myMainVwr->DefinedViewIterator()); aDefViewIter.More(); aDefViewIter.Next())
|
||||
@@ -2099,8 +2094,7 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t
|
||||
}
|
||||
}
|
||||
|
||||
if (theToUpdateviewer
|
||||
&& theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if (theToUpdateviewer && aStatus->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
}
|
||||
@@ -2114,13 +2108,14 @@ void AIS_InteractiveContext::ClearGlobalPrs (const Handle(AIS_InteractiveObject)
|
||||
const Standard_Integer theMode,
|
||||
const Standard_Boolean theToUpdateViewer)
|
||||
{
|
||||
const Handle(AIS_GlobalStatus)* aStatus = !theIObj.IsNull() ? myObjects.Seek (theIObj) : NULL;
|
||||
if (aStatus == NULL)
|
||||
if (theIObj.IsNull()
|
||||
|| !myObjects.IsBound (theIObj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*aStatus)->DisplayMode() == theMode)
|
||||
const Handle(AIS_GlobalStatus)& aStatus = myObjects (theIObj);
|
||||
if (aStatus->DisplayMode() == theMode)
|
||||
{
|
||||
const Standard_Integer aDispMode = theIObj->HasHilightMode() ? theIObj->HilightMode() : 0;
|
||||
if (aDispMode == theMode
|
||||
@@ -2132,7 +2127,7 @@ void AIS_InteractiveContext::ClearGlobalPrs (const Handle(AIS_InteractiveObject)
|
||||
myMainPM->Erase (theIObj, theMode);
|
||||
}
|
||||
|
||||
if (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
if (aStatus->GraphicStatus() == AIS_DS_Displayed
|
||||
&& theToUpdateViewer)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
@@ -2567,34 +2562,28 @@ gp_Pnt AIS_InteractiveContext::GravityPoint (const Handle(V3d_View)& theView) co
|
||||
{
|
||||
return theView->GravityPoint();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : setObjectStatus
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::setObjectStatus (const Handle(AIS_InteractiveObject)& theIObj,
|
||||
const PrsMgr_DisplayStatus theStatus,
|
||||
const AIS_DisplayStatus theStatus,
|
||||
const Standard_Integer theDispMode,
|
||||
const Standard_Integer theSelectionMode)
|
||||
{
|
||||
theIObj->SetDisplayStatus (theStatus);
|
||||
if (theStatus != PrsMgr_DisplayStatus_None)
|
||||
if (theStatus != AIS_DS_None)
|
||||
{
|
||||
Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus (theDispMode, theSelectionMode);
|
||||
Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus (AIS_DS_Displayed, theDispMode, theSelectionMode);
|
||||
myObjects.Bind (theIObj, aStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
myObjects.UnBind (theIObj);
|
||||
}
|
||||
|
||||
for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (theIObj->Children()); aPrsIter.More(); aPrsIter.Next())
|
||||
{
|
||||
Handle(AIS_InteractiveObject) aChild (Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()));
|
||||
if (aChild.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
setObjectStatus (aChild, theStatus, theDispMode, theSelectionMode);
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ public: //! @name object display management
|
||||
//! - AIS_DS_Erased hidden in main viewer
|
||||
//! - AIS_DS_Temporary temporarily displayed
|
||||
//! - AIS_DS_None nowhere displayed.
|
||||
Standard_EXPORT PrsMgr_DisplayStatus DisplayStatus (const Handle(AIS_InteractiveObject)& anIobj) const;
|
||||
Standard_EXPORT AIS_DisplayStatus DisplayStatus (const Handle(AIS_InteractiveObject)& anIobj) const;
|
||||
|
||||
//! Returns the status of the Interactive Context for the view of the Interactive Object.
|
||||
Standard_EXPORT void Status (const Handle(AIS_InteractiveObject)& anObj, TCollection_ExtendedString& astatus) const;
|
||||
@@ -110,7 +110,7 @@ public: //! @name object display management
|
||||
const Standard_Integer theDispMode,
|
||||
const Standard_Integer theSelectionMode,
|
||||
const Standard_Boolean theToUpdateViewer,
|
||||
const PrsMgr_DisplayStatus theDispStatus = PrsMgr_DisplayStatus_None);
|
||||
const AIS_DisplayStatus theDispStatus = AIS_DS_None);
|
||||
|
||||
//! Allows you to load the Interactive Object with a given selection mode,
|
||||
//! and/or with the desired decomposition option, whether the object is visualized or not.
|
||||
@@ -123,7 +123,7 @@ public: //! @name object display management
|
||||
const Standard_Integer theSelectionMode,
|
||||
const Standard_Boolean theToUpdateViewer,
|
||||
const Standard_Boolean theToAllowDecomposition,
|
||||
const PrsMgr_DisplayStatus theDispStatus = PrsMgr_DisplayStatus_None)
|
||||
const AIS_DisplayStatus theDispStatus = AIS_DS_None)
|
||||
{
|
||||
(void )theToAllowDecomposition;
|
||||
Display (theIObj, theDispMode, theSelectionMode, theToUpdateViewer, theDispStatus);
|
||||
@@ -805,14 +805,11 @@ public: //! @name common properties
|
||||
|
||||
//! Returns the list theListOfIO of objects with indicated display status particular Type WhichKind and Signature WhichSignature.
|
||||
//! By Default, WhichSignature equals 1. This means that there is a check on type only.
|
||||
Standard_EXPORT void ObjectsByDisplayStatus (const PrsMgr_DisplayStatus theStatus, AIS_ListOfInteractive& theListOfIO) const;
|
||||
Standard_EXPORT void ObjectsByDisplayStatus (const AIS_DisplayStatus theStatus, AIS_ListOfInteractive& theListOfIO) const;
|
||||
|
||||
//! gives the list of objects with indicated display status
|
||||
//! Type and signature by Default, <WhichSignature> = -1 means control only on <WhichKind>.
|
||||
Standard_EXPORT void ObjectsByDisplayStatus (const AIS_KindOfInteractive WhichKind,
|
||||
const Standard_Integer WhichSignature,
|
||||
const PrsMgr_DisplayStatus theStatus,
|
||||
AIS_ListOfInteractive& theListOfIO) const;
|
||||
Standard_EXPORT void ObjectsByDisplayStatus (const AIS_KindOfInteractive WhichKind, const Standard_Integer WhichSignature, const AIS_DisplayStatus theStatus, AIS_ListOfInteractive& theListOfIO) const;
|
||||
|
||||
//! fills <aListOfIO> with objects of a particular Type and Signature with no consideration of display status.
|
||||
//! by Default, <WhichSignature> = -1 means control only on <WhichKind>.
|
||||
@@ -826,10 +823,7 @@ public: //! @name common properties
|
||||
Standard_EXPORT void Disconnect (const Handle(AIS_InteractiveObject)& theAssembly, const Handle(AIS_InteractiveObject)& theObjToDisconnect = NULL);
|
||||
|
||||
//! Query objects visible or hidden in specified view due to affinity mask.
|
||||
Standard_EXPORT void ObjectsForView (AIS_ListOfInteractive& theListOfIO,
|
||||
const Handle(V3d_View)& theView,
|
||||
const Standard_Boolean theIsVisibleInView,
|
||||
const PrsMgr_DisplayStatus theStatus = PrsMgr_DisplayStatus_None) const;
|
||||
Standard_EXPORT void ObjectsForView (AIS_ListOfInteractive& theListOfIO, const Handle(V3d_View)& theView, const Standard_Boolean theIsVisibleInView, const AIS_DisplayStatus theStatus = AIS_DS_None) const;
|
||||
|
||||
//! Clears all the structures which don't belong to objects displayed at neutral point
|
||||
//! only effective when no Local Context is opened...
|
||||
@@ -1396,7 +1390,7 @@ protected: //! @name internal methods
|
||||
//! @param theObj [in] the object to change status
|
||||
//! @param theStatus status, if NULL, unbind object
|
||||
Standard_EXPORT void setObjectStatus (const Handle(AIS_InteractiveObject)& theIObj,
|
||||
const PrsMgr_DisplayStatus theStatus,
|
||||
const AIS_DisplayStatus theStatus,
|
||||
const Standard_Integer theDispyMode,
|
||||
const Standard_Integer theSelectionMode);
|
||||
|
||||
|
@@ -247,10 +247,8 @@ void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObj
|
||||
for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjsIter (myObjects); anObjsIter.More(); anObjsIter.Next())
|
||||
{
|
||||
const Handle(AIS_GlobalStatus)& aStatus = anObjsIter.Value();
|
||||
if (theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly)
|
||||
{
|
||||
if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
|
||||
continue;
|
||||
}
|
||||
|
||||
aStatus->SubIntensityOn();
|
||||
myMainPM->Color (anObjsIter.Key(), aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
|
||||
@@ -260,14 +258,10 @@ void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObj
|
||||
{
|
||||
Handle(AIS_GlobalStatus) aStatus;
|
||||
if (!myObjects.Find (theObject, aStatus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly)
|
||||
{
|
||||
if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
|
||||
return;
|
||||
}
|
||||
|
||||
aStatus->SubIntensityOn();
|
||||
myMainPM->Color (theObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
|
||||
|
@@ -66,7 +66,7 @@ void AIS_InteractiveContext::SetSelectionModeActive (const Handle(AIS_Interactiv
|
||||
|| (theMode == -1
|
||||
&& theActiveFilter == AIS_SelectionModesConcurrency_Single))
|
||||
{
|
||||
if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
if ((*aStat)->GraphicStatus() == AIS_DS_Displayed
|
||||
|| theIsForce)
|
||||
{
|
||||
if (theMode == -1)
|
||||
@@ -103,7 +103,7 @@ void AIS_InteractiveContext::SetSelectionModeActive (const Handle(AIS_Interactiv
|
||||
return;
|
||||
}
|
||||
|
||||
if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
|
||||
if ((*aStat)->GraphicStatus() == AIS_DS_Displayed
|
||||
|| theIsForce)
|
||||
{
|
||||
switch (theActiveFilter)
|
||||
@@ -247,7 +247,7 @@ void AIS_InteractiveContext::SubIntensityOff (const Handle(AIS_InteractiveObject
|
||||
|
||||
(*aStatus)->SubIntensityOff();
|
||||
Standard_Boolean toUpdateMain = Standard_False;
|
||||
if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
if ((*aStatus)->GraphicStatus() == AIS_DS_Displayed)
|
||||
{
|
||||
myMainPM->Unhighlight (theObj);
|
||||
toUpdateMain = Standard_True;
|
||||
|
@@ -53,11 +53,12 @@ void AIS_InteractiveContext::SetPolygonOffsets(
|
||||
setContextToObject (anObj);
|
||||
anObj->SetPolygonOffsets( aMode, aFactor, aUnits );
|
||||
|
||||
const Handle(AIS_GlobalStatus)* aStatus = updateviewer ? myObjects.Seek (anObj) : NULL;
|
||||
if (aStatus != NULL
|
||||
&& anObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
|
||||
{
|
||||
myMainVwr->Update();
|
||||
if ( updateviewer ) {
|
||||
if( myObjects.IsBound( anObj ) ) {
|
||||
Handle(AIS_GlobalStatus) STATUS = myObjects(anObj);
|
||||
if ( STATUS->GraphicStatus() == AIS_DS_Displayed )
|
||||
myMainVwr->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -83,15 +83,6 @@ void AIS_InteractiveObject::SetContext (const Handle(AIS_InteractiveContext)& th
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetDisplayStatus
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_InteractiveObject::SetDisplayStatus (PrsMgr_DisplayStatus theStatus)
|
||||
{
|
||||
myDisplayStatus = theStatus;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasPresentation
|
||||
//purpose :
|
||||
|
@@ -126,9 +126,6 @@ protected:
|
||||
//! may have a presentation dependant of the view of Display.
|
||||
Standard_EXPORT AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d = PrsMgr_TOP_AllView);
|
||||
|
||||
//! Set presentation display status.
|
||||
Standard_EXPORT void SetDisplayStatus (PrsMgr_DisplayStatus theStatus);
|
||||
|
||||
protected:
|
||||
|
||||
AIS_InteractiveContext* myCTXPtr; //!< pointer to Interactive Context, where object is currently displayed; @sa SetContext()
|
||||
|
@@ -41,12 +41,10 @@ AIS_TextLabel::AIS_TextLabel()
|
||||
myFont ("Courier"),
|
||||
myFontAspect (Font_FA_Regular),
|
||||
myHasOrientation3D (Standard_False),
|
||||
myHasOwnAnchorPoint (Standard_True),
|
||||
myHasFlipping (Standard_False)
|
||||
{
|
||||
myDrawer->SetTextAspect (new Prs3d_TextAspect());
|
||||
|
||||
SetDisplayMode (0);
|
||||
myDrawer->SetDisplayMode (0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -309,12 +307,7 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
|
||||
|
||||
gp_Ax2 anOrientation = myOrientation3D;
|
||||
anOrientation.SetLocation (aPosition);
|
||||
|
||||
Standard_Boolean aHasOwnAnchor = HasOwnAnchorPoint();
|
||||
if (myHasFlipping)
|
||||
aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
|
||||
|
||||
Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, aHasOwnAnchor);
|
||||
Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, !myHasFlipping);
|
||||
if (myHasFlipping && isInit)
|
||||
{
|
||||
Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_False, gp_Ax2());
|
||||
|
@@ -32,6 +32,9 @@ public:
|
||||
//! Default constructor
|
||||
Standard_EXPORT AIS_TextLabel();
|
||||
|
||||
//! Return TRUE for supported display mode.
|
||||
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
|
||||
|
||||
//! Setup color of entire text.
|
||||
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
|
||||
|
||||
@@ -90,12 +93,6 @@ public:
|
||||
|
||||
Standard_EXPORT Standard_Boolean HasFlipping() const;
|
||||
|
||||
//! Returns flag if text uses position as point of attach
|
||||
Standard_Boolean HasOwnAnchorPoint() const { return myHasOwnAnchorPoint; }
|
||||
|
||||
//! Set flag if text uses position as point of attach
|
||||
void SetOwnAnchorPoint (const Standard_Boolean theOwnAnchorPoint) { myHasOwnAnchorPoint = theOwnAnchorPoint; }
|
||||
|
||||
//! Define the display type of the text.
|
||||
//!
|
||||
//! TODT_NORMAL Default display. Text only.
|
||||
@@ -127,7 +124,6 @@ protected:
|
||||
Font_FontAspect myFontAspect;
|
||||
gp_Ax2 myOrientation3D;
|
||||
Standard_Boolean myHasOrientation3D;
|
||||
Standard_Boolean myHasOwnAnchorPoint;
|
||||
Standard_Boolean myHasFlipping;
|
||||
|
||||
public:
|
||||
|
@@ -69,6 +69,7 @@ AIS_ViewController::AIS_ViewController()
|
||||
myMousePressed (Aspect_VKeyMouse_NONE),
|
||||
myMouseModifiers (Aspect_VKeyFlags_NONE),
|
||||
myMouseSingleButton (-1),
|
||||
myMouseStopDragOnUnclick (false),
|
||||
//
|
||||
myTouchToleranceScale (1.0f),
|
||||
myTouchRotationThresholdPx (6.0f),
|
||||
@@ -611,6 +612,7 @@ bool AIS_ViewController::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
|
||||
{
|
||||
myMouseClickTimer.Stop();
|
||||
myMouseClickCounter = 0;
|
||||
myMouseStopDragOnUnclick = false;
|
||||
myUI.Dragging.ToStop = true;
|
||||
toUpdateView = true;
|
||||
}
|
||||
@@ -619,6 +621,12 @@ bool AIS_ViewController::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
|
||||
else if (theButtons == Aspect_VKeyMouse_NONE)
|
||||
{
|
||||
myMouseSingleButton = -1;
|
||||
if (myMouseStopDragOnUnclick)
|
||||
{
|
||||
myMouseStopDragOnUnclick = false;
|
||||
myUI.Dragging.ToStop = true;
|
||||
toUpdateView = true;
|
||||
}
|
||||
}
|
||||
else if (myMouseSingleButton == -1)
|
||||
{
|
||||
@@ -769,6 +777,7 @@ bool AIS_ViewController::UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
|
||||
myMouseClickTimer.Stop();
|
||||
myMouseClickCounter = 0;
|
||||
myMouseSingleButton = -1;
|
||||
myMouseStopDragOnUnclick = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -647,6 +647,7 @@ protected: //! @name mouse input variables
|
||||
Aspect_VKeyMouse myMousePressed; //!< active mouse buttons
|
||||
Aspect_VKeyFlags myMouseModifiers; //!< active key modifiers passed with last mouse event
|
||||
Standard_Integer myMouseSingleButton; //!< index of mouse button pressed alone (>0)
|
||||
Standard_Boolean myMouseStopDragOnUnclick; //!< queue stop dragging even with at next mouse unclick
|
||||
|
||||
protected: //! @name multi-touch input variables
|
||||
|
||||
|
@@ -137,6 +137,9 @@ AIS_ViewCube::AIS_ViewCube()
|
||||
myBoxEdgeGap (0.0),
|
||||
myBoxFacetExtension (1.0),
|
||||
myAxesPadding (1.0),
|
||||
myAxesRadius (1.0),
|
||||
myAxesConeRadius (3.0),
|
||||
myAxesSphereRadius (4.0),
|
||||
myCornerMinSize (2.0),
|
||||
myRoundRadius (0.0),
|
||||
myToDisplayAxes (true),
|
||||
@@ -599,7 +602,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
anAxisGroup->SetGroupPrimitivesAspect (aDatumAspect->ShadingAspect (aPart)->Aspect());
|
||||
|
||||
const Standard_Real anArrowLength = 0.2 * anAxisSize;
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, 1.0, anAxisSize, 3.0, anArrowLength, THE_NB_ARROW_FACETTES);
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, myAxesRadius, anAxisSize, myAxesConeRadius, anArrowLength, THE_NB_ARROW_FACETTES);
|
||||
anAxisGroup->AddPrimitiveArray (aTriangleArray);
|
||||
|
||||
TCollection_AsciiString anAxisLabel;
|
||||
@@ -621,7 +624,7 @@ void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect();
|
||||
anAspectCen->SetColor (Quantity_NOC_WHITE);
|
||||
aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
|
||||
Prs3d_ToolSphere aTool (4.0, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
|
||||
Prs3d_ToolSphere aTool (myAxesSphereRadius, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
|
||||
Handle(Graphic3d_ArrayOfTriangles) aCenterArray;
|
||||
|
@@ -189,6 +189,45 @@ public: //! @name Geometry management API
|
||||
//! The value should be within [0, 0.5] range.
|
||||
Standard_EXPORT void SetRoundRadius (const Standard_Real theValue);
|
||||
|
||||
//! Returns radius of axes of the trihedron; 1.0 by default.
|
||||
Standard_Real AxesRadius() const { return myAxesRadius; }
|
||||
|
||||
//! Sets radius of axes of the trihedron.
|
||||
void SetAxesRadius (const Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns radius of cone of axes of the trihedron; 3.0 by default.
|
||||
Standard_Real AxesConeRadius() const { return myAxesConeRadius; }
|
||||
|
||||
//! Sets radius of cone of axes of the trihedron.
|
||||
void SetAxesConeRadius (Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesConeRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesConeRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns radius of sphere (central point) of the trihedron; 4.0 by default.
|
||||
Standard_Real AxesSphereRadius() const { return myAxesSphereRadius; }
|
||||
|
||||
//! Sets radius of sphere (central point) of the trihedron.
|
||||
void SetAxesSphereRadius (Standard_Real theRadius)
|
||||
{
|
||||
if (Abs (myAxesSphereRadius - theRadius) > Precision::Confusion())
|
||||
{
|
||||
myAxesSphereRadius = theRadius;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! @return TRUE if trihedron is drawn; TRUE by default.
|
||||
Standard_Boolean ToDrawAxes() const { return myToDisplayAxes; }
|
||||
|
||||
@@ -621,6 +660,9 @@ protected:
|
||||
Standard_Real myBoxEdgeGap; //!< gap between box side and box edge
|
||||
Standard_Real myBoxFacetExtension; //!< box facet extension
|
||||
Standard_Real myAxesPadding; //!< Padding between box and axes
|
||||
Standard_Real myAxesRadius; //!< radius of axes of the trihedron; 1.0 by default
|
||||
Standard_Real myAxesConeRadius; //!< radius of cone of axes of the trihedron; 3.0 by default
|
||||
Standard_Real myAxesSphereRadius; //!< radius of sphere (central point) of the trihedron; 4.0 by default
|
||||
Standard_Real myCornerMinSize; //!< minimal size of box corner
|
||||
Standard_Real myRoundRadius; //!< relative round radius within [0; 0.5] range
|
||||
Standard_Boolean myToDisplayAxes; //!< trihedron visibility
|
||||
|
@@ -27,8 +27,10 @@
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <Geom2dAdaptor_HCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomAdaptor_HCurve.hxx>
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <GeomConvert.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Precision.hxx>
|
||||
@@ -300,6 +302,10 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Approx_CurveOnSurface
|
||||
//purpose : Constructor
|
||||
//=============================================================================
|
||||
Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D,
|
||||
const Handle(Adaptor3d_HSurface)& Surf,
|
||||
const Standard_Real First,
|
||||
@@ -310,14 +316,75 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
const Standard_Integer MaxSegments,
|
||||
const Standard_Boolean only3d,
|
||||
const Standard_Boolean only2d)
|
||||
: myC2D(C2D),
|
||||
mySurf(Surf),
|
||||
myFirst(First),
|
||||
myLast(Last),
|
||||
myTol(Tol),
|
||||
myIsDone(Standard_False),
|
||||
myHasResult(Standard_False),
|
||||
myError3d(0.0),
|
||||
myError2dU(0.0),
|
||||
myError2dV(0.0)
|
||||
{
|
||||
Perform(MaxSegments, MaxDegree, S, only3d, only2d);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Approx_CurveOnSurface
|
||||
//purpose : Constructor
|
||||
//=============================================================================
|
||||
Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
|
||||
const Handle(Adaptor3d_HSurface)& theSurf,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real theTol)
|
||||
: myC2D(theC2D),
|
||||
mySurf(theSurf),
|
||||
myFirst(theFirst),
|
||||
myLast(theLast),
|
||||
myTol(theTol),
|
||||
myIsDone(Standard_False),
|
||||
myHasResult(Standard_False),
|
||||
myError3d(0.0),
|
||||
myError2dU(0.0),
|
||||
myError2dV(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
|
||||
const Standard_Integer theMaxDegree,
|
||||
const GeomAbs_Shape theContinuity,
|
||||
const Standard_Boolean theOnly3d,
|
||||
const Standard_Boolean theOnly2d)
|
||||
{
|
||||
myIsDone = Standard_False;
|
||||
if(only3d && only2d) throw Standard_ConstructionError();
|
||||
GeomAbs_Shape Order = S;
|
||||
myHasResult = Standard_False;
|
||||
myError2dU = 0.0;
|
||||
myError2dV = 0.0;
|
||||
myError3d = 0.0;
|
||||
|
||||
Handle( Adaptor2d_HCurve2d ) TrimmedC2D = C2D->Trim( First, Last, Precision::PConfusion() );
|
||||
if(theOnly3d && theOnly2d) throw Standard_ConstructionError();
|
||||
|
||||
Adaptor3d_CurveOnSurface COnS( TrimmedC2D, Surf );
|
||||
Handle( Adaptor2d_HCurve2d ) TrimmedC2D = myC2D->Trim( myFirst, myLast, Precision::PConfusion() );
|
||||
|
||||
Standard_Boolean isU, isForward;
|
||||
Standard_Real aParam;
|
||||
if (theOnly3d && isIsoLine(TrimmedC2D, isU, aParam, isForward))
|
||||
{
|
||||
if (buildC3dOnIsoLine(TrimmedC2D, isU, aParam, isForward))
|
||||
{
|
||||
myIsDone = Standard_True;
|
||||
myHasResult = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Adaptor3d_CurveOnSurface COnS( TrimmedC2D, mySurf );
|
||||
Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface();
|
||||
HCOnS->Set(COnS);
|
||||
|
||||
@@ -327,37 +394,34 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
Handle(TColStd_HArray1OfReal) ThreeDTol;
|
||||
|
||||
// create evaluators and choose appropriate one
|
||||
Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS, First, Last);
|
||||
Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf ( TrimmedC2D, First, Last);
|
||||
Approx_CurveOnSurface_Eval EvalCvOnSurf (HCOnS, TrimmedC2D, First, Last);
|
||||
Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS, myFirst, myLast);
|
||||
Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf ( TrimmedC2D, myFirst, myLast);
|
||||
Approx_CurveOnSurface_Eval EvalCvOnSurf (HCOnS, TrimmedC2D, myFirst, myLast);
|
||||
AdvApprox_EvaluatorFunction* EvalPtr;
|
||||
if ( only3d ) EvalPtr = &Eval3dCvOnSurf;
|
||||
else if ( only2d ) EvalPtr = &Eval2dCvOnSurf;
|
||||
if ( theOnly3d ) EvalPtr = &Eval3dCvOnSurf;
|
||||
else if ( theOnly2d ) EvalPtr = &Eval2dCvOnSurf;
|
||||
else EvalPtr = &EvalCvOnSurf;
|
||||
|
||||
// Initialization for 2d approximation
|
||||
if(!only3d) {
|
||||
if(!theOnly3d) {
|
||||
Num1DSS = 2;
|
||||
OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
|
||||
|
||||
Standard_Real TolU, TolV;
|
||||
|
||||
TolU = Surf->UResolution(Tol)/2;
|
||||
TolV = Surf->VResolution(Tol)/2;
|
||||
TolU = mySurf->UResolution(myTol)/2;
|
||||
TolV = mySurf->VResolution(myTol)/2;
|
||||
|
||||
OneDTol->SetValue(1,TolU);
|
||||
OneDTol->SetValue(2,TolV);
|
||||
}
|
||||
|
||||
if(!only2d) {
|
||||
if(!theOnly2d) {
|
||||
Num3DSS=1;
|
||||
ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
|
||||
ThreeDTol->Init(Tol/2);
|
||||
ThreeDTol->Init(myTol/2);
|
||||
}
|
||||
|
||||
myError2dU = 0;
|
||||
myError2dV = 0;
|
||||
myError3d = 0;
|
||||
|
||||
Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
|
||||
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
|
||||
@@ -369,8 +433,8 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
|
||||
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
|
||||
OneDTol, TwoDTolNul, ThreeDTol,
|
||||
First, Last, Order,
|
||||
MaxDegree, MaxSegments,
|
||||
myFirst, myLast, theContinuity,
|
||||
theMaxDegree, theMaxSegments,
|
||||
*EvalPtr, CutTool);
|
||||
|
||||
myIsDone = aApprox.IsDone();
|
||||
@@ -381,14 +445,14 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
|
||||
Standard_Integer Degree = aApprox.Degree();
|
||||
|
||||
if(!only2d)
|
||||
if(!theOnly2d)
|
||||
{
|
||||
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
|
||||
aApprox.Poles(1,Poles);
|
||||
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
|
||||
myError3d = aApprox.MaxError(3, 1);
|
||||
}
|
||||
if(!only3d)
|
||||
if(!theOnly3d)
|
||||
{
|
||||
TColgp_Array1OfPnt2d Poles2d(1,aApprox.NbPoles());
|
||||
TColStd_Array1OfReal Poles1dU(1,aApprox.NbPoles());
|
||||
@@ -404,8 +468,6 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Approx_CurveOnSurface::IsDone() const
|
||||
@@ -443,3 +505,161 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
|
||||
return myError2dV;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : isIsoLine
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Approx_CurveOnSurface::isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
|
||||
Standard_Boolean& theIsU,
|
||||
Standard_Real& theParam,
|
||||
Standard_Boolean& theIsForward) const
|
||||
{
|
||||
// These variables are used to check line state (vertical or horizontal).
|
||||
Standard_Boolean isAppropriateType = Standard_False;
|
||||
gp_Pnt2d aLoc2d;
|
||||
gp_Dir2d aDir2d;
|
||||
|
||||
// Test type.
|
||||
const GeomAbs_CurveType aType = theC2D->GetType();
|
||||
if (aType == GeomAbs_Line)
|
||||
{
|
||||
gp_Lin2d aLin2d = theC2D->Line();
|
||||
aLoc2d = aLin2d.Location();
|
||||
aDir2d = aLin2d.Direction();
|
||||
isAppropriateType = Standard_True;
|
||||
}
|
||||
else if (aType == GeomAbs_BSplineCurve)
|
||||
{
|
||||
Handle(Geom2d_BSplineCurve) aBSpline2d = theC2D->BSpline();
|
||||
if (aBSpline2d->Degree() != 1 || aBSpline2d->NbPoles() != 2)
|
||||
return Standard_False; // Not a line or uneven parameterization.
|
||||
|
||||
aLoc2d = aBSpline2d->Pole(1);
|
||||
|
||||
// Vector should be non-degenerated.
|
||||
gp_Vec2d aVec2d(aBSpline2d->Pole(1), aBSpline2d->Pole(2));
|
||||
if (aVec2d.SquareMagnitude() < Precision::Confusion())
|
||||
return Standard_False; // Degenerated spline.
|
||||
aDir2d = aVec2d;
|
||||
|
||||
isAppropriateType = Standard_True;
|
||||
}
|
||||
else if (aType == GeomAbs_BezierCurve)
|
||||
{
|
||||
Handle(Geom2d_BezierCurve) aBezier2d = theC2D->Bezier();
|
||||
if (aBezier2d->Degree() != 1 || aBezier2d->NbPoles() != 2)
|
||||
return Standard_False; // Not a line or uneven parameterization.
|
||||
|
||||
aLoc2d = aBezier2d->Pole(1);
|
||||
|
||||
// Vector should be non-degenerated.
|
||||
gp_Vec2d aVec2d(aBezier2d->Pole(1), aBezier2d->Pole(2));
|
||||
if (aVec2d.SquareMagnitude() < Precision::Confusion())
|
||||
return Standard_False; // Degenerated spline.
|
||||
aDir2d = aVec2d;
|
||||
|
||||
isAppropriateType = Standard_True;
|
||||
}
|
||||
|
||||
if (!isAppropriateType)
|
||||
return Standard_False;
|
||||
|
||||
// Check line to be vertical or horizontal.
|
||||
if (aDir2d.IsParallel(gp::DX2d(), Precision::Angular()))
|
||||
{
|
||||
// Horizontal line. V = const.
|
||||
theIsU = Standard_False;
|
||||
theParam = aLoc2d.Y();
|
||||
theIsForward = aDir2d.Dot(gp::DX2d()) > 0.0;
|
||||
return Standard_True;
|
||||
}
|
||||
else if (aDir2d.IsParallel(gp::DY2d(), Precision::Angular()))
|
||||
{
|
||||
// Vertical line. U = const.
|
||||
theIsU = Standard_True;
|
||||
theParam = aLoc2d.X();
|
||||
theIsForward = aDir2d.Dot(gp::DY2d()) > 0.0;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
#include <GeomLib.hxx>
|
||||
|
||||
//=============================================================================
|
||||
//function : buildC3dOnIsoLine
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Approx_CurveOnSurface::buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
|
||||
const Standard_Boolean theIsU,
|
||||
const Standard_Real theParam,
|
||||
const Standard_Boolean theIsForward)
|
||||
{
|
||||
// Convert adapter to the appropriate type.
|
||||
Handle(GeomAdaptor_HSurface) aGeomAdapter = Handle(GeomAdaptor_HSurface)::DownCast(mySurf);
|
||||
if (aGeomAdapter.IsNull())
|
||||
return Standard_False;
|
||||
|
||||
if (mySurf->GetType() == GeomAbs_Sphere)
|
||||
return Standard_False;
|
||||
|
||||
// Extract isoline
|
||||
Handle(Geom_Surface) aSurf = aGeomAdapter->ChangeSurface().Surface();
|
||||
Handle(Geom_Curve) aC3d;
|
||||
|
||||
gp_Pnt2d aF2d = theC2D->Value(theC2D->FirstParameter());
|
||||
gp_Pnt2d aL2d = theC2D->Value(theC2D->LastParameter());
|
||||
|
||||
if (theIsU)
|
||||
{
|
||||
aC3d = aSurf->UIso(theParam);
|
||||
aC3d = new Geom_TrimmedCurve(aC3d, aF2d.Y(), aL2d.Y());
|
||||
}
|
||||
else
|
||||
{
|
||||
aC3d = aSurf->VIso(theParam);
|
||||
aC3d = new Geom_TrimmedCurve(aC3d, aF2d.X(), aL2d.X());
|
||||
}
|
||||
|
||||
// Convert arbitrary curve type to the b-spline.
|
||||
myCurve3d = GeomConvert::CurveToBSplineCurve(aC3d, Convert_QuasiAngular);
|
||||
if (!theIsForward)
|
||||
myCurve3d->Reverse();
|
||||
|
||||
// Rebuild parameterization for the 3d curve to have the same parameterization with
|
||||
// a two-dimensional curve.
|
||||
TColStd_Array1OfReal aKnots = myCurve3d->Knots();
|
||||
BSplCLib::Reparametrize(theC2D->FirstParameter(), theC2D->LastParameter(), aKnots);
|
||||
myCurve3d->SetKnots(aKnots);
|
||||
|
||||
// Evaluate error.
|
||||
myError3d = 0.0;
|
||||
|
||||
const Standard_Real aParF = myFirst;
|
||||
const Standard_Real aParL = myLast;
|
||||
const Standard_Integer aNbPnt = 23;
|
||||
for(Standard_Integer anIdx = 0; anIdx <= aNbPnt; ++anIdx)
|
||||
{
|
||||
const Standard_Real aPar = aParF + ((aParL - aParF) * anIdx) / aNbPnt;
|
||||
|
||||
const gp_Pnt2d aPnt2d = theC2D->Value(aPar);
|
||||
|
||||
const gp_Pnt aPntC3D = myCurve3d->Value(aPar);
|
||||
const gp_Pnt aPntC2D = mySurf->Value(aPnt2d.X(), aPnt2d.Y());
|
||||
|
||||
const Standard_Real aSqDeviation = aPntC3D.SquareDistance(aPntC2D);
|
||||
myError3d = Max(aSqDeviation, myError3d);
|
||||
}
|
||||
|
||||
myError3d = Sqrt(myError3d);
|
||||
|
||||
// Target tolerance is not obtained. This situation happens for isolines on the sphere.
|
||||
// OCCT is unable to convert it keeping original parameterization, while the geometric
|
||||
// form of the result is entirely identical. In that case, it is better to utilize
|
||||
// a general-purpose approach.
|
||||
if (myError3d > myTol)
|
||||
return Standard_False;
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -40,9 +40,22 @@ public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! This constructor calls perform method. This constructor is deprecated.
|
||||
Standard_DEPRECATED("This constructor is deprecated. Use other constructor and perform method instead.")
|
||||
Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D, const Handle(Adaptor3d_HSurface)& Surf, const Standard_Real First, const Standard_Real Last, const Standard_Real Tol, const GeomAbs_Shape Continuity, const Standard_Integer MaxDegree, const Standard_Integer MaxSegments, const Standard_Boolean Only3d = Standard_False, const Standard_Boolean Only2d = Standard_False);
|
||||
|
||||
|
||||
//! This constructor does not call perform method.
|
||||
//! @param theC2D 2D Curve to be approximated in 3D.
|
||||
//! @param theSurf Surface where 2D curve is located.
|
||||
//! @param theFirst First parameter of resulting curve.
|
||||
//! @param theFirst Last parameter of resulting curve.
|
||||
//! @param theTol Computation tolerance.
|
||||
Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
|
||||
const Handle(Adaptor3d_HSurface)& theSurf,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real theTol);
|
||||
|
||||
Standard_EXPORT Standard_Boolean IsDone() const;
|
||||
|
||||
Standard_EXPORT Standard_Boolean HasResult() const;
|
||||
@@ -59,18 +72,64 @@ public:
|
||||
//! 2d Curve
|
||||
Standard_EXPORT Standard_Real MaxError2dV() const;
|
||||
|
||||
|
||||
|
||||
//! Constructs the 3d curve. Input parameters are ignored when the input curve is
|
||||
//! U-isoline or V-isoline.
|
||||
//! @param theMaxSegments Maximal number of segments in the resulting spline.
|
||||
//! @param theMaxDegree Maximal degree of the result.
|
||||
//! @param theContinuity Resulting continuity.
|
||||
//! @param theOnly3d Determines building only 3D curve.
|
||||
//! @param theOnly2d Determines building only 2D curve.
|
||||
Standard_EXPORT void Perform(const Standard_Integer theMaxSegments,
|
||||
const Standard_Integer theMaxDegree,
|
||||
const GeomAbs_Shape theContinuity,
|
||||
const Standard_Boolean theOnly3d = Standard_False,
|
||||
const Standard_Boolean theOnly2d = Standard_False);
|
||||
|
||||
protected:
|
||||
|
||||
//! Checks whether the 2d curve is a isoline. It can be represented by b-spline, bezier,
|
||||
//! or geometric line. This line should have natural parameterization.
|
||||
//! @param theC2D Trimmed curve to be checked.
|
||||
//! @param theIsU Flag indicating that line is u const.
|
||||
//! @param theParam Line parameter.
|
||||
//! @param theIsForward Flag indicating forward parameterization on a isoline.
|
||||
//! @return Standard_True when 2d curve is a line and Standard_False otherwise.
|
||||
Standard_Boolean isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
|
||||
Standard_Boolean& theIsU,
|
||||
Standard_Real& theParam,
|
||||
Standard_Boolean& theIsForward) const;
|
||||
|
||||
//! Builds 3D curve for a isoline. This method takes corresponding isoline from
|
||||
//! the input surface.
|
||||
//! @param theC2D Trimmed curve to be approximated.
|
||||
//! @param theIsU Flag indicating that line is u const.
|
||||
//! @param theParam Line parameter.
|
||||
//! @param theIsForward Flag indicating forward parameterization on a isoline.
|
||||
//! @return Standard_True when 3d curve is built and Standard_False otherwise.
|
||||
Standard_Boolean buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
|
||||
const Standard_Boolean theIsU,
|
||||
const Standard_Real theParam,
|
||||
const Standard_Boolean theIsForward);
|
||||
|
||||
|
||||
private:
|
||||
Approx_CurveOnSurface& operator= (const Approx_CurveOnSurface&);
|
||||
|
||||
private:
|
||||
|
||||
//! Input curve.
|
||||
const Handle(Adaptor2d_HCurve2d) myC2D;
|
||||
|
||||
//! Input surface.
|
||||
const Handle(Adaptor3d_HSurface) mySurf;
|
||||
|
||||
//! First parameter of the result.
|
||||
const Standard_Real myFirst;
|
||||
|
||||
//! Last parameter of the result.
|
||||
const Standard_Real myLast;
|
||||
|
||||
//! Tolerance.
|
||||
Standard_Real myTol;
|
||||
|
||||
Handle(Geom2d_BSplineCurve) myCurve2d;
|
||||
Handle(Geom_BSplineCurve) myCurve3d;
|
||||
|
@@ -25,7 +25,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Aspect_DisplayConnection,Standard_Transient)
|
||||
// =======================================================================
|
||||
Aspect_DisplayConnection::Aspect_DisplayConnection()
|
||||
{
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
myDisplay = NULL;
|
||||
myIsOwnDisplay = false;
|
||||
OSD_Environment anEnv ("DISPLAY");
|
||||
@@ -40,7 +40,7 @@ Aspect_DisplayConnection::Aspect_DisplayConnection()
|
||||
// =======================================================================
|
||||
Aspect_DisplayConnection::~Aspect_DisplayConnection()
|
||||
{
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
if (myDisplay != NULL
|
||||
&& myIsOwnDisplay)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ Aspect_DisplayConnection::~Aspect_DisplayConnection()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
// =======================================================================
|
||||
// function : Aspect_DisplayConnection
|
||||
// purpose :
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
#include <InterfaceGraphic.hxx>
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
//! Destructor. Close opened connection.
|
||||
Standard_EXPORT ~Aspect_DisplayConnection();
|
||||
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
//! Constructor. Creates connection with display specified in theDisplayName.
|
||||
//! Display name should be in format "hostname:number" or "hostname:number.screen_number", where:
|
||||
//! hostname - Specifies the name of the host machine on which the display is physically attached.
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#ifndef _Aspect_FBConfig_HeaderFile
|
||||
#define _Aspect_FBConfig_HeaderFile
|
||||
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
typedef struct __GLXFBConfigRec* GLXFBConfig;
|
||||
typedef GLXFBConfig Aspect_FBConfig; // GLXFBConfig* under UNIX
|
||||
#else
|
||||
|
@@ -59,7 +59,7 @@ public:
|
||||
virtual void Unmap() const Standard_OVERRIDE { myIsMapped = Standard_False; }
|
||||
|
||||
//! Resize window - do nothing.
|
||||
virtual Aspect_TypeOfResize DoResize() const Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
|
||||
virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE { return Aspect_TOR_UNKNOWN; }
|
||||
|
||||
//! Map window - do nothing.
|
||||
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
Standard_EXPORT virtual void Unmap() const = 0;
|
||||
|
||||
//! Apply the resizing to the window <me>.
|
||||
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() const = 0;
|
||||
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() = 0;
|
||||
|
||||
//! Apply the mapping change to the window <me>.
|
||||
//! and returns TRUE if the window is mapped at screen.
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#ifndef __Aspect_WNTXWD_HXX
|
||||
# define __Aspect_WNTXWD_HXX
|
||||
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
|
||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||
# include <X11/XWDFile.h>
|
||||
# else
|
||||
|
||||
|
@@ -89,28 +89,63 @@ class BOPAlgo_EdgeEdge :
|
||||
Handle(BOPDS_PaveBlock)& PaveBlock2() {
|
||||
return myPB2;
|
||||
}
|
||||
//
|
||||
//
|
||||
void SetBoxes (const Bnd_Box& theBox1,
|
||||
const Bnd_Box& theBox2)
|
||||
{
|
||||
myBox1 = theBox1;
|
||||
myBox2 = theBox2;
|
||||
}
|
||||
//
|
||||
void SetFuzzyValue(const Standard_Real theFuzz) {
|
||||
IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
|
||||
}
|
||||
//
|
||||
virtual void Perform() {
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
TopoDS_Edge anE1 = myEdge1, anE2 = myEdge2;
|
||||
Standard_Boolean hasTrsf = false;
|
||||
try
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
gp_Trsf aTrsf;
|
||||
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
|
||||
{
|
||||
// Shapes are located far from origin, move the shapes to the origin,
|
||||
// to increase the accuracy of intersection.
|
||||
TopLoc_Location aLoc (aTrsf);
|
||||
myEdge1.Move (aLoc);
|
||||
myEdge2.Move (aLoc);
|
||||
hasTrsf = Standard_True;
|
||||
}
|
||||
|
||||
IntTools_EdgeEdge::Perform();
|
||||
}
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
AddError(new BOPAlgo_AlertIntersectionFailed);
|
||||
}
|
||||
|
||||
myEdge1 = anE1;
|
||||
myEdge2 = anE2;
|
||||
if (hasTrsf)
|
||||
{
|
||||
for (Standard_Integer i = 1; i <= myCommonParts.Length(); ++i)
|
||||
{
|
||||
IntTools_CommonPrt& aCPart = myCommonParts (i);
|
||||
aCPart.SetEdge1 (myEdge1);
|
||||
aCPart.SetEdge2 (myEdge2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
protected:
|
||||
Handle(BOPDS_PaveBlock) myPB1;
|
||||
Handle(BOPDS_PaveBlock) myPB2;
|
||||
Bnd_Box myBox1;
|
||||
Bnd_Box myBox2;
|
||||
};
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -216,6 +251,7 @@ void BOPAlgo_PaveFiller::PerformEE()
|
||||
//
|
||||
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
|
||||
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
|
||||
anEdgeEdge.SetBoxes (aBB1, aBB2);
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
|
||||
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
|
||||
}//for (; aIt2.More(); aIt2.Next()) {
|
||||
@@ -924,6 +960,8 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
|
||||
if (!aNbPB)
|
||||
return;
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Prepare pave blocks with the same vertices for intersection.
|
||||
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
|
||||
|
||||
@@ -940,10 +978,12 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// Use the max tolerance of vertices as Fuzzy value for intersection
|
||||
// of edges
|
||||
Standard_Real aTolAdd = 2 * Max(BRep_Tool::Tolerance(aV1),
|
||||
BRep_Tool::Tolerance(aV2));
|
||||
// Use the max tolerance of vertices as Fuzzy value for intersection of edges.
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
// All possible pairs combined from the list <aLPB> should be checked
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
|
||||
@@ -1022,6 +1062,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
|
||||
anEdgeEdge.SetPaveBlock2(aPB2);
|
||||
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
|
||||
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
|
||||
anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
|
||||
if (bUseAddTol)
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
else
|
||||
|
@@ -105,18 +105,50 @@ class BOPAlgo_EdgeFace :
|
||||
IntTools_EdgeFace::SetFuzzyValue(theFuzz);
|
||||
}
|
||||
//
|
||||
void SetBoxes (const Bnd_Box& theBox1,
|
||||
const Bnd_Box& theBox2)
|
||||
{
|
||||
myBox1 = theBox1;
|
||||
myBox2 = theBox2;
|
||||
}
|
||||
//
|
||||
virtual void Perform() {
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
TopoDS_Face aFace = myFace;
|
||||
TopoDS_Edge anEdge = myEdge;
|
||||
Standard_Boolean hasTrsf = false;
|
||||
try
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
gp_Trsf aTrsf;
|
||||
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
|
||||
{
|
||||
// Shapes are located far from origin, move the shapes to the origin,
|
||||
// to increase the accuracy of intersection.
|
||||
TopLoc_Location aLoc (aTrsf);
|
||||
myEdge.Move (aLoc);
|
||||
myFace.Move (aLoc);
|
||||
hasTrsf = Standard_True;
|
||||
}
|
||||
|
||||
IntTools_EdgeFace::Perform();
|
||||
}
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
AddError(new BOPAlgo_AlertIntersectionFailed);
|
||||
}
|
||||
myFace = aFace;
|
||||
myEdge = anEdge;
|
||||
|
||||
if (hasTrsf)
|
||||
{
|
||||
for (Standard_Integer i = 1; i <= mySeqOfCommonPrts.Length(); ++i)
|
||||
{
|
||||
IntTools_CommonPrt& aCPart = mySeqOfCommonPrts (i);
|
||||
aCPart.SetEdge1 (myEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
protected:
|
||||
@@ -124,6 +156,8 @@ class BOPAlgo_EdgeFace :
|
||||
Standard_Integer myIF;
|
||||
IntTools_Range myNewSR;
|
||||
Handle(BOPDS_PaveBlock) myPB;
|
||||
Bnd_Box myBox1;
|
||||
Bnd_Box myBox2;
|
||||
};
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -231,6 +265,7 @@ void BOPAlgo_PaveFiller::PerformEF()
|
||||
//
|
||||
aEdgeFace.SetEdge (aE);
|
||||
aEdgeFace.SetFace (aF);
|
||||
aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
|
||||
aEdgeFace.SetFuzzyValue(myFuzzyValue);
|
||||
aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
|
||||
//
|
||||
@@ -756,6 +791,8 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
|
||||
// Shake the tree
|
||||
aBBTree.Build();
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Find pairs of Face/PaveBlock containing the same vertices
|
||||
// and prepare those pairs for intersection.
|
||||
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
|
||||
@@ -874,8 +911,12 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
|
||||
// tolerance as the criteria.
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
Standard_Real aTolCheck = 2 * Max(BRep_Tool::Tolerance(aV1),
|
||||
BRep_Tool::Tolerance(aV2));
|
||||
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
|
||||
continue;
|
||||
@@ -940,6 +981,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
|
||||
aEdgeFace.SetPaveBlock(aPB);
|
||||
aEdgeFace.SetEdge(aE);
|
||||
aEdgeFace.SetFace(aF);
|
||||
aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
|
||||
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
|
||||
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
|
||||
|
@@ -122,6 +122,12 @@ class BOPAlgo_FaceFace :
|
||||
myF2=aF2;
|
||||
}
|
||||
//
|
||||
void SetBoxes(const Bnd_Box& theBox1,
|
||||
const Bnd_Box& theBox2) {
|
||||
myBox1 = theBox1;
|
||||
myBox2 = theBox2;
|
||||
}
|
||||
//
|
||||
const TopoDS_Face& Face1()const {
|
||||
return myF1;
|
||||
}
|
||||
@@ -142,13 +148,37 @@ class BOPAlgo_FaceFace :
|
||||
IntTools_FaceFace::SetFuzzyValue(theFuzz);
|
||||
}
|
||||
//
|
||||
const gp_Trsf& Trsf() const { return myTrsf; }
|
||||
//
|
||||
virtual void Perform() {
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
try
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
IntTools_FaceFace::Perform(myF1, myF2);
|
||||
gp_Trsf aTrsf;
|
||||
TopoDS_Face aF1 = myF1, aF2 = myF2;
|
||||
if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
|
||||
{
|
||||
// Shapes are located far from origin, move the shapes to the origin,
|
||||
// to increase the accuracy of intersection.
|
||||
TopLoc_Location aLoc (aTrsf);
|
||||
aF1.Move (aLoc);
|
||||
aF2.Move (aLoc);
|
||||
|
||||
// The starting point is initialized only with the UV parameters
|
||||
// on the faces - 3D point is not set (see GetEFPnts method),
|
||||
// so no need to transform anything.
|
||||
//for (IntSurf_ListOfPntOn2S::Iterator it (myListOfPnts); it.More(); it.Next())
|
||||
//{
|
||||
// IntSurf_PntOn2S& aP2S = it.ChangeValue();
|
||||
// aP2S.SetValue (aP2S.Value().Transformed (aTrsf));
|
||||
//}
|
||||
|
||||
myTrsf = aTrsf.Inverted();
|
||||
}
|
||||
|
||||
IntTools_FaceFace::Perform (aF1, aF2);
|
||||
}
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
@@ -156,12 +186,39 @@ class BOPAlgo_FaceFace :
|
||||
}
|
||||
}
|
||||
//
|
||||
void ApplyTrsf()
|
||||
{
|
||||
if (IsDone())
|
||||
{
|
||||
// Update curves
|
||||
for (Standard_Integer i = 1; i <= mySeqOfCurve.Length(); ++i)
|
||||
{
|
||||
IntTools_Curve& aIC = mySeqOfCurve (i);
|
||||
aIC.Curve()->Transform (myTrsf);
|
||||
}
|
||||
// Update points
|
||||
for (Standard_Integer i = 1; i <= myPnts.Length(); ++i)
|
||||
{
|
||||
IntTools_PntOn2Faces& aP2F = myPnts (i);
|
||||
IntTools_PntOnFace aPOnF1 = aP2F.P1(), aPOnF2 = aP2F.P2();
|
||||
aPOnF1.SetPnt (aPOnF1.Pnt().Transformed (myTrsf));
|
||||
aPOnF2.SetPnt (aPOnF2.Pnt().Transformed (myTrsf));
|
||||
aP2F.SetP1 (aPOnF1);
|
||||
aP2F.SetP2 (aPOnF2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
protected:
|
||||
Standard_Integer myIF1;
|
||||
Standard_Integer myIF2;
|
||||
Standard_Real myTolFF;
|
||||
TopoDS_Face myF1;
|
||||
TopoDS_Face myF2;
|
||||
Bnd_Box myBox1;
|
||||
Bnd_Box myBox2;
|
||||
gp_Trsf myTrsf;
|
||||
};
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -235,6 +292,7 @@ void BOPAlgo_PaveFiller::PerformFF()
|
||||
//
|
||||
aFaceFace.SetIndices(nF1, nF2);
|
||||
aFaceFace.SetFaces(aF1, aF2);
|
||||
aFaceFace.SetBoxes (myDS->ShapeInfo (nF1).Box(), myDS->ShapeInfo (nF2).Box());
|
||||
// compute minimal tolerance for the curves
|
||||
Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
|
||||
aFaceFace.SetTolFF(aTolFF);
|
||||
@@ -282,6 +340,8 @@ void BOPAlgo_PaveFiller::PerformFF()
|
||||
//
|
||||
aFaceFace.PrepareLines3D(bSplitCurve);
|
||||
//
|
||||
aFaceFace.ApplyTrsf();
|
||||
//
|
||||
const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
|
||||
const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
|
||||
//
|
||||
@@ -1711,12 +1771,16 @@ void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
|
||||
getBoundPaves(myDS, aNC, aBndNV);
|
||||
//
|
||||
Standard_Real aTolVnew = Precision::Confusion();
|
||||
Standard_Boolean isClosed = aP[1].IsEqual (aP[0], aTolVnew);
|
||||
if (isClosed && (aBndNV[0] > 0 || aBndNV[1] > 0))
|
||||
return;
|
||||
|
||||
for (Standard_Integer j = 0; j<2; ++j)
|
||||
{
|
||||
if (aBndNV[j] < 0)
|
||||
{
|
||||
// no vertex on this end
|
||||
if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
|
||||
if (j && isClosed) {
|
||||
//if curve is closed, process only one bound
|
||||
continue;
|
||||
}
|
||||
|
@@ -215,11 +215,15 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
|
||||
//
|
||||
// use only connected faces
|
||||
TopTools_ListOfShape aLFConnected;
|
||||
// Boundary faces
|
||||
TopTools_MapOfShape aBoundaryFaces;
|
||||
aItF.Initialize (myShapes);
|
||||
for (; aItF.More(); aItF.Next()) {
|
||||
const TopoDS_Shape& aF = aItF.Value();
|
||||
if (aMFaces.Contains(aF)) {
|
||||
aLFConnected.Append(aF);
|
||||
if (!aBoundaryFaces.Add (aF))
|
||||
aBoundaryFaces.Remove (aF);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -254,6 +258,7 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
|
||||
aItS.Initialize(aShell);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
|
||||
Standard_Boolean isBoundary = aBoundaryFaces.Contains (aF);
|
||||
//
|
||||
// loop on edges of aF; find a good neighbor face of aF by aE
|
||||
aExp.Init(aF, TopAbs_EDGE);
|
||||
@@ -289,6 +294,8 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
|
||||
// take only not-processed faces as a candidates
|
||||
BOPTools_ListOfCoupleOfShape aLCSOff;
|
||||
//
|
||||
Standard_Integer aNbWaysInside = 0;
|
||||
TopoDS_Face aSelF;
|
||||
TopTools_ListIteratorOfListOfShape aItLF(aLF);
|
||||
for (; aItLF.More(); aItLF.Next()) {
|
||||
const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value()));
|
||||
@@ -301,6 +308,11 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (isBoundary && !aBoundaryFaces.Contains (aFL))
|
||||
{
|
||||
++aNbWaysInside;
|
||||
aSelF = aFL;
|
||||
}
|
||||
aCSOff.SetShape1(aEL);
|
||||
aCSOff.SetShape2(aFL);
|
||||
aLCSOff.Append(aCSOff);
|
||||
@@ -313,12 +325,14 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
|
||||
//
|
||||
// among all the adjacent faces chose one with the minimal
|
||||
// angle to the current one
|
||||
TopoDS_Face aSelF;
|
||||
if (aNbOff == 1) {
|
||||
aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
|
||||
}
|
||||
else if (aNbOff > 1) {
|
||||
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
|
||||
if (!isBoundary || aNbWaysInside != 1)
|
||||
{
|
||||
if (aNbOff == 1) {
|
||||
aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
|
||||
}
|
||||
else if (aNbOff > 1) {
|
||||
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
|
||||
}
|
||||
}
|
||||
//
|
||||
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
|
||||
|
@@ -1756,3 +1756,30 @@ void BOPAlgo_Tools::FillInternals(const TopTools_ListOfShape& theSolids,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TrsfToPoint
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BOPAlgo_Tools::TrsfToPoint (const Bnd_Box& theBox1,
|
||||
const Bnd_Box& theBox2,
|
||||
gp_Trsf& theTrsf,
|
||||
const gp_Pnt& thePoint,
|
||||
const Standard_Real theCriteria)
|
||||
{
|
||||
// Unify two boxes
|
||||
Bnd_Box aBox = theBox1;
|
||||
aBox.Add (theBox2);
|
||||
|
||||
gp_XYZ aBCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) / 2.;
|
||||
Standard_Real aPBDist = (thePoint.XYZ() - aBCenter).Modulus();
|
||||
if (aPBDist < theCriteria)
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real aBSize = Sqrt (aBox.SquareExtent());
|
||||
if ((aBSize / aPBDist) > (1. / theCriteria))
|
||||
return Standard_False;
|
||||
|
||||
theTrsf.SetTranslation (gp_Vec (aBox.CornerMin(), thePoint));
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -205,6 +205,20 @@ public:
|
||||
const TopTools_DataMapOfShapeListOfShape& theImages,
|
||||
const Handle(IntTools_Context)& theContext);
|
||||
|
||||
//! Computes the transformation needed to move the objects
|
||||
//! to the given point to increase the quality of computations.
|
||||
//! Returns true if the objects are located far from the given point
|
||||
//! (relatively given criteria), false otherwise.
|
||||
//! @param theBox1 the AABB of the first object
|
||||
//! @param theBox2 the AABB of the second object
|
||||
//! @param theTrsf the computed transformation
|
||||
//! @param thePoint the Point to compute transformation to
|
||||
//! @param theCriteria the Criteria to check whether thranformation is required
|
||||
Standard_EXPORT static Standard_Boolean TrsfToPoint (const Bnd_Box& theBox1,
|
||||
const Bnd_Box& theBox2,
|
||||
gp_Trsf& theTrsf,
|
||||
const gp_Pnt& thePoint = gp_Pnt (0.0, 0.0, 0.0),
|
||||
const Standard_Real theCriteria = 1.e+5);
|
||||
};
|
||||
|
||||
#endif // _BOPAlgo_Tools_HeaderFile
|
||||
|
@@ -27,7 +27,9 @@ class BOPAlgo_EdgeInfo {
|
||||
BOPAlgo_EdgeInfo() :
|
||||
myPassed(Standard_False),
|
||||
myInFlag(Standard_False),
|
||||
myAngle (-1.) {
|
||||
myIsInside (Standard_False),
|
||||
myAngle (-1.)
|
||||
{
|
||||
};
|
||||
//
|
||||
void SetEdge(const TopoDS_Edge& theE) {
|
||||
@@ -62,10 +64,19 @@ class BOPAlgo_EdgeInfo {
|
||||
return myAngle;
|
||||
};
|
||||
//
|
||||
Standard_Boolean IsInside() const {
|
||||
return myIsInside;
|
||||
};
|
||||
//
|
||||
void SetIsInside (const Standard_Boolean theIsInside) {
|
||||
myIsInside = theIsInside;
|
||||
};
|
||||
//
|
||||
protected:
|
||||
TopoDS_Edge myEdge;
|
||||
Standard_Boolean myPassed;
|
||||
Standard_Boolean myInFlag;
|
||||
Standard_Boolean myIsInside;
|
||||
Standard_Real myAngle;
|
||||
};
|
||||
|
||||
|
@@ -166,6 +166,8 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
|
||||
MyDataMapOfShapeBoolean aVertMap;
|
||||
//
|
||||
const TopTools_ListOfShape& myEdges=aCB.Shapes();
|
||||
|
||||
TopTools_MapOfShape aMS;
|
||||
//
|
||||
// 1.Filling mySmartMap
|
||||
aIt.Initialize(myEdges);
|
||||
@@ -177,6 +179,10 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
|
||||
//
|
||||
bIsClosed = BRep_Tool::Degenerated(aE) ||
|
||||
BRep_Tool::IsClosed(aE, myFace);
|
||||
|
||||
if (!aMS.Add (aE) && !bIsClosed)
|
||||
aMS.Remove (aE);
|
||||
|
||||
//
|
||||
aItS.Initialize(aE);
|
||||
for(i = 0; aItS.More(); aItS.Next(), ++i) {
|
||||
@@ -218,7 +224,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
|
||||
for (i=1; i<=aNb; i++) {
|
||||
aCntIn=0;
|
||||
aCntOut=0;
|
||||
const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
|
||||
const BOPAlgo_ListOfEdgeInfo& aLEInfo = mySmartMap(i);
|
||||
BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
|
||||
for (; anIt.More(); anIt.Next()) {
|
||||
const BOPAlgo_EdgeInfo& aEI=anIt.Value();
|
||||
@@ -304,6 +310,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
|
||||
for (; aItLEI.More(); aItLEI.Next()) {
|
||||
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
|
||||
const TopoDS_Edge& aE=aEI.Edge();
|
||||
aEI.SetIsInside (!aMS.Contains (aE));
|
||||
//
|
||||
aVV = aV;
|
||||
bIsIN = aEI.IsIn();
|
||||
@@ -366,7 +373,7 @@ void Path (const GeomAdaptor_Surface& aGAS,
|
||||
Standard_Integer i, j, aNb, aNbj;
|
||||
Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
|
||||
Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
|
||||
Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
|
||||
Standard_Boolean anIsSameV2d, anIsSameV, anIsOut, anIsNotPassed;
|
||||
Standard_Boolean bIsClosed;
|
||||
TopoDS_Vertex aVa, aVb;
|
||||
TopoDS_Edge aEOuta;
|
||||
@@ -501,8 +508,12 @@ void Path (const GeomAdaptor_Surface& aGAS,
|
||||
//
|
||||
anAngleIn = AngleIn(aEOuta, aLEInfo);
|
||||
aMinAngle = 100.;
|
||||
anIsFound = Standard_False;
|
||||
Standard_Integer iCnt = NbWaysOut(aLEInfo);
|
||||
|
||||
Standard_Boolean isBoundary = !anEdgeInfo->IsInside();
|
||||
Standard_Integer aNbWaysInside = 0;
|
||||
BOPAlgo_EdgeInfo *pOnlyWayIn = NULL;
|
||||
|
||||
Standard_Integer aCurIndexE = 0;
|
||||
anIt.Initialize(aLEInfo);
|
||||
for (; anIt.More(); anIt.Next()) {
|
||||
@@ -525,7 +536,6 @@ void Path (const GeomAdaptor_Surface& aGAS,
|
||||
if (iCnt==1) {
|
||||
// the one and only way to go out .
|
||||
pEdgeInfo=&anEI;
|
||||
anIsFound=Standard_True;
|
||||
break;
|
||||
}
|
||||
//
|
||||
@@ -548,15 +558,25 @@ void Path (const GeomAdaptor_Surface& aGAS,
|
||||
anAngleOut=anEI.Angle();
|
||||
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
|
||||
}
|
||||
|
||||
if (isBoundary && anEI.IsInside())
|
||||
{
|
||||
++aNbWaysInside;
|
||||
pOnlyWayIn = &anEI;
|
||||
}
|
||||
|
||||
if (anAngle < aMinAngle - eps) {
|
||||
aMinAngle=anAngle;
|
||||
pEdgeInfo=&anEI;
|
||||
anIsFound=Standard_True;
|
||||
}
|
||||
}
|
||||
} // for (; anIt.More(); anIt.Next())
|
||||
if (aNbWaysInside == 1)
|
||||
{
|
||||
pEdgeInfo = pOnlyWayIn;
|
||||
}
|
||||
//
|
||||
if (!anIsFound) {
|
||||
if (!pEdgeInfo) {
|
||||
// no way to go . (Error)
|
||||
return;
|
||||
}
|
||||
|
@@ -525,6 +525,7 @@ namespace {
|
||||
struct EdgeData {
|
||||
const TopoDS_Edge* Edge; // Edge
|
||||
Standard_Real VParameter; // Parameter of the vertex on the edge
|
||||
Standard_Boolean IsClosed; // Closed flag of the edge
|
||||
Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
|
||||
Standard_Real First; // First parameter in the range
|
||||
Standard_Real Last; // Last parameter in the rage
|
||||
@@ -610,9 +611,9 @@ static
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (Abs(aTint1 - aT1) > aHalfR1 ||
|
||||
Abs(aTint2 - aT2) > aHalfR2) {
|
||||
// intersection on the other end of the closed edge
|
||||
if ((!theEData1.IsClosed && Abs (aTint1 - aT1) > aHalfR1) ||
|
||||
(!theEData2.IsClosed && Abs (aTint2 - aT2) > aHalfR2)) {
|
||||
// intersection is on the other end of the edge
|
||||
continue;
|
||||
}
|
||||
//
|
||||
@@ -634,7 +635,7 @@ void CorrectWires(const TopoDS_Face& aFx,
|
||||
const TopTools_IndexedMapOfShape& aMapToAvoid)
|
||||
{
|
||||
Standard_Integer i, aNbV;
|
||||
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
|
||||
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2;
|
||||
gp_Pnt aP, aPV;
|
||||
gp_Pnt2d aP2D;
|
||||
TopoDS_Face aF;
|
||||
@@ -644,11 +645,9 @@ void CorrectWires(const TopoDS_Face& aFx,
|
||||
aF=aFx;
|
||||
aF.Orientation(TopAbs_FORWARD);
|
||||
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
|
||||
//
|
||||
TopExp::MapShapesAndAncestors(aF,
|
||||
TopAbs_VERTEX,
|
||||
TopAbs_EDGE,
|
||||
aMVE);
|
||||
|
||||
TopExp::MapShapesAndUniqueAncestors (aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE, Standard_True);
|
||||
|
||||
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
|
||||
aNbV=aMVE.Extent();
|
||||
for (i=1; i<=aNbV; ++i) {
|
||||
@@ -666,7 +665,13 @@ void CorrectWires(const TopoDS_Face& aFx,
|
||||
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
|
||||
const Handle(Geom2d_Curve)& aC2D=
|
||||
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
|
||||
aT=BRep_Tool::Parameter(aV, aE);
|
||||
Standard_Real aT = BRep_Tool::Parameter (aV, aE);
|
||||
Standard_Boolean isClosed = Standard_False;
|
||||
{
|
||||
TopoDS_Vertex aV1, aV2;
|
||||
TopExp::Vertices (aE, aV1, aV2);
|
||||
isClosed = aV1.IsSame (aV2);
|
||||
}
|
||||
//
|
||||
aC2D->D0(aT, aP2D);
|
||||
aS->D0(aP2D.X(), aP2D.Y(), aP);
|
||||
@@ -674,7 +679,7 @@ void CorrectWires(const TopoDS_Face& aFx,
|
||||
if (aD2>aD2max) {
|
||||
aD2max=aD2;
|
||||
}
|
||||
EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
|
||||
EdgeData anEData = {&aE, aT, isClosed, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
|
||||
aLEPars.Append(anEData);
|
||||
}
|
||||
//
|
||||
|
@@ -363,9 +363,8 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
|
||||
#ifdef OCCT_DEBUG_CHRONO
|
||||
InitChron(chr_approx);
|
||||
#endif
|
||||
Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d,
|
||||
myContinuity, myMaxDegree, myMaxSeg,
|
||||
Only3d, Only2d);
|
||||
Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d);
|
||||
appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d);
|
||||
#ifdef OCCT_DEBUG_CHRONO
|
||||
ResultChron(chr_approx,t_approx);
|
||||
approx_count++;
|
||||
|
@@ -126,8 +126,8 @@ Standard_Real BRepBlend_AppSurface::TolCurveOnSurf(const Standard_Integer Index)
|
||||
return approx.TolCurveOnSurf(Index);
|
||||
}
|
||||
|
||||
inline void BRepBlend_AppSurface::TolReached (Standard_Real& Tol3d,
|
||||
Standard_Real& Tol2d) const
|
||||
void BRepBlend_AppSurface::TolReached (Standard_Real& Tol3d,
|
||||
Standard_Real& Tol2d) const
|
||||
{
|
||||
Tol3d = approx.MaxErrorOnSurf();
|
||||
Tol2d = 0;
|
||||
|
@@ -1055,6 +1055,7 @@ void BRepFeat_MakeRevolutionForm::Perform()
|
||||
if(ex1.Current().IsSame(e1)) {
|
||||
myLFMap(iter.Key()).Clear();
|
||||
myLFMap(iter.Key()).Append(ex2.Current());
|
||||
break; // break the cycle (e1 became a dead reference)
|
||||
}
|
||||
ex2.Next();
|
||||
}
|
||||
@@ -1062,16 +1063,14 @@ void BRepFeat_MakeRevolutionForm::Perform()
|
||||
|
||||
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter1(mySlface);
|
||||
for(; iter1.More(); iter1.Next()) {
|
||||
const TopoDS_Shape& f1 = iter1.Key();
|
||||
const TopoDS_Shape& e1 = iter1.Value().First();
|
||||
TopExp_Explorer ex1(myPbase, TopAbs_EDGE);
|
||||
TopExp_Explorer ex2(Pbase, TopAbs_EDGE);
|
||||
for(; ex1.More(); ex1.Next()) {
|
||||
const TopoDS_Shape& E1 = ex1.Current();
|
||||
const TopoDS_Shape& E2 = ex2.Current();
|
||||
if(E1.IsSame(e1)) {
|
||||
mySlface(f1).Clear();
|
||||
mySlface(f1).Append(E2);
|
||||
if(ex1.Current().IsSame(e1)) {
|
||||
mySlface(iter1.Key()).Clear();
|
||||
mySlface(iter1.Key()).Append(ex2.Current());
|
||||
break; // break the cycle (e1 became a dead reference)
|
||||
}
|
||||
ex2.Next();
|
||||
}
|
||||
@@ -1158,9 +1157,9 @@ void BRepFeat_MakeRevolutionForm::Perform()
|
||||
const TopoDS_Shape& sh = it1.Value().First();
|
||||
exx.Init(VraiForm, TopAbs_FACE);
|
||||
for(; exx.More(); exx.Next()) {
|
||||
const TopoDS_Face& fac = TopoDS::Face(exx.Current());
|
||||
TopoDS_Face fac = TopoDS::Face(exx.Current());
|
||||
TopExp_Explorer exx1(fac, TopAbs_WIRE);
|
||||
const TopoDS_Wire& thew = TopoDS::Wire(exx1.Current());
|
||||
TopoDS_Wire thew = TopoDS::Wire(exx1.Current());
|
||||
if(thew.IsSame(myFShape)) {
|
||||
const TopTools_ListOfShape& desfaces = trP.Modified(f2);
|
||||
myMap(myFShape) = desfaces;
|
||||
@@ -1172,13 +1171,13 @@ void BRepFeat_MakeRevolutionForm::Perform()
|
||||
continue;
|
||||
}
|
||||
if(fac.IsSame(sh)) {
|
||||
if (trP.IsDeleted(fac)) {
|
||||
}
|
||||
else {
|
||||
if (! trP.IsDeleted(fac))
|
||||
{
|
||||
const TopTools_ListOfShape& desfaces = trP.Modified(fac);
|
||||
if(!desfaces.IsEmpty()) {
|
||||
myMap(orig).Clear();
|
||||
myMap(orig) = trP.Modified(fac);
|
||||
break; // break the cycle (sh became a dead reference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -149,9 +149,6 @@ static void TrimEdge (const TopoDS_Edge& Edge,
|
||||
TColStd_SequenceOfReal& ThePar,
|
||||
TopTools_SequenceOfShape& S);
|
||||
|
||||
static TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
|
||||
const TopoDS_Face& F);
|
||||
|
||||
static Standard_Integer PosOnFace (Standard_Real d1,
|
||||
Standard_Real d2,
|
||||
Standard_Real d3);
|
||||
@@ -986,8 +983,8 @@ void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face& Sp,
|
||||
// skin => same orientation E[0] , inverted orientation E[2]
|
||||
// if contreskin it is inverted.
|
||||
//--------------------------------------------------------------
|
||||
E[0].Orientation(OriEdgeInFace(E[0],F[0]));
|
||||
E[2].Orientation(OriEdgeInFace(E[2],F[1]));
|
||||
E[0].Orientation(BRepTools::OriEdgeInFace(E[0],F[0]));
|
||||
E[2].Orientation(BRepTools::OriEdgeInFace(E[2],F[1]));
|
||||
|
||||
if (DistanceToOZ(VF) < DistanceToOZ(VL) ) {
|
||||
// Skin
|
||||
@@ -1199,14 +1196,14 @@ void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face& Sp,
|
||||
TopTools_ListIteratorOfListOfShape itl;
|
||||
const TopTools_ListOfShape& LF = myMap(CurrentSpine)(VCF);
|
||||
|
||||
TopAbs_Orientation Ori = OriEdgeInFace(TopoDS::Edge(LF.First()),
|
||||
TopAbs_Orientation Ori = BRepTools::OriEdgeInFace(TopoDS::Edge(LF.First()),
|
||||
CurrentFace);
|
||||
for (itl.Initialize(LF), itl.Next(); itl.More(); itl.Next()) {
|
||||
TopoDS_Edge RE = TopoDS::Edge(itl.Value());
|
||||
MapBis(CurrentFace).Append(RE.Oriented(Ori));
|
||||
}
|
||||
const TopTools_ListOfShape& LL = myMap(CurrentSpine)(VCL);
|
||||
Ori = OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
|
||||
Ori = BRepTools::OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
|
||||
for (itl.Initialize(LL), itl.Next() ; itl.More(); itl.Next()) {
|
||||
TopoDS_Edge RE = TopoDS::Edge(itl.Value());
|
||||
MapBis(CurrentFace).Append(RE.Oriented(Ori));
|
||||
@@ -2920,26 +2917,6 @@ static TopAbs_Orientation Relative (const TopoDS_Wire& W1,
|
||||
|
||||
return TopAbs_REVERSED;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : OriEdgeInFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
|
||||
const TopoDS_Face& F )
|
||||
|
||||
{
|
||||
TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
||||
|
||||
for (; Exp.More() ;Exp.Next()) {
|
||||
if (Exp.Current().IsSame(E)) {
|
||||
return Exp.Current().Orientation();
|
||||
}
|
||||
}
|
||||
throw Standard_ConstructionError("BRepFill_Evolved::OriEdgeInFace");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsOnFace
|
||||
|
@@ -451,7 +451,12 @@ void BRepFill_LocationLaw::CurvilinearBounds(const Standard_Integer Index,
|
||||
|
||||
Standard_Boolean BRepFill_LocationLaw::IsClosed() const
|
||||
{
|
||||
return myPath.Closed();
|
||||
if (myPath.Closed())
|
||||
return Standard_True;
|
||||
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(myPath, V1, V2);
|
||||
return (V1.IsSame(V2));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -1377,7 +1377,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
|
||||
BB.Add(aWire, CurEdge);
|
||||
} //for (jj = 2; jj <= SeqEdges.Length(); jj++)
|
||||
//case of closed wire
|
||||
if (mySection->IsVClosed() &&
|
||||
if (myLocation->IsClosed() &&
|
||||
!CurVertex.IsSame(FirstVertex))
|
||||
{
|
||||
const TopTools_ListOfShape& Elist = VEmap.FindFromKey(CurVertex);
|
||||
|
@@ -330,8 +330,9 @@ static Standard_Boolean SameParameter(TopoDS_Edge& E,
|
||||
if (!HasPCurves(E))
|
||||
{
|
||||
Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
|
||||
Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
|
||||
Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
|
||||
Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
|
||||
Precision::Confusion());
|
||||
AppCurve.Perform(10, 10, GeomAbs_C1, Standard_True);
|
||||
if (AppCurve.IsDone() && AppCurve.HasResult())
|
||||
{
|
||||
C3d = AppCurve.Curve3d();
|
||||
|
@@ -1347,15 +1347,13 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
}
|
||||
|
||||
// Eval tol2d to compute SameRange
|
||||
Standard_Real UResol = Max(GAS.UResolution(theTolerance), Precision::PConfusion());
|
||||
Standard_Real VResol = Max(GAS.VResolution(theTolerance), Precision::PConfusion());
|
||||
Standard_Real Tol2d = Min(UResol, VResol);
|
||||
Standard_Real TolSameRange = Max(GAC.Resolution(theTolerance), Precision::PConfusion());
|
||||
for(Standard_Integer i = 0; i < 2; i++){
|
||||
Handle(Geom2d_Curve) curPC = PC[i];
|
||||
Standard_Boolean updatepc = 0;
|
||||
if(curPC.IsNull()) break;
|
||||
if(!SameRange){
|
||||
GeomLib::SameRange(Tol2d,
|
||||
GeomLib::SameRange(TolSameRange,
|
||||
PC[i],GCurve->First(),GCurve->Last(),
|
||||
f3d,l3d,curPC);
|
||||
|
||||
@@ -1375,13 +1373,17 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
|
||||
if(GAC2d.GetType() == GeomAbs_BSplineCurve &&
|
||||
GAC2d.Continuity() == GeomAbs_C0) {
|
||||
Standard_Real UResol = GAS.UResolution(theTolerance);
|
||||
Standard_Real VResol = GAS.VResolution(theTolerance);
|
||||
Standard_Real TolConf2d = Min(UResol, VResol);
|
||||
TolConf2d = Max(TolConf2d, Precision::PConfusion());
|
||||
Handle(Geom2d_BSplineCurve) bs2d = GAC2d.BSpline();
|
||||
Handle(Geom2d_BSplineCurve) bs2dsov = bs2d;
|
||||
Standard_Real fC0 = bs2d->FirstParameter(), lC0 = bs2d->LastParameter();
|
||||
Standard_Boolean repar = Standard_True;
|
||||
gp_Pnt2d OriginPoint;
|
||||
bs2d->D0(fC0, OriginPoint);
|
||||
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, Tol2d);
|
||||
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, TolConf2d);
|
||||
isBSP = Standard_True;
|
||||
|
||||
if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000
|
||||
@@ -1425,7 +1427,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
}
|
||||
d = sqrt(d)*.1;
|
||||
|
||||
Tol2dbail = Max(Min(Tol2dbail,d),Tol2d);
|
||||
Tol2dbail = Max(Min(Tol2dbail,d), TolConf2d);
|
||||
|
||||
Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d,Tol2dbail);
|
||||
|
||||
@@ -1531,8 +1533,8 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
GAC2d.Load(bs2d,f3d,l3d);
|
||||
curPC = bs2d;
|
||||
|
||||
if(Abs(bs2d->FirstParameter() - fC0) > Tol2d ||
|
||||
Abs(bs2d->LastParameter() - lC0) > Tol2d ) {
|
||||
if(Abs(bs2d->FirstParameter() - fC0) > TolSameRange ||
|
||||
Abs(bs2d->LastParameter() - lC0) > TolSameRange) {
|
||||
Standard_Integer NbKnots = bs2d->NbKnots();
|
||||
TColStd_Array1OfReal Knots(1,NbKnots);
|
||||
bs2d->Knots(Knots);
|
||||
@@ -1585,7 +1587,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
//Approx_SameParameter has failed.
|
||||
//Consequently, the situation might be,
|
||||
//when 3D and 2D-curve do not have same-range.
|
||||
GeomLib::SameRange( Tol2d, PC[i],
|
||||
GeomLib::SameRange( TolSameRange, PC[i],
|
||||
GCurve->First(), GCurve->Last(),
|
||||
f3d,l3d,curPC);
|
||||
|
||||
@@ -1831,6 +1833,12 @@ void BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape)
|
||||
for (Standard_Integer i = 1; i <= EFmap.Extent(); i++)
|
||||
{
|
||||
TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i));
|
||||
|
||||
if (!BRep_Tool::IsGeometric(anEdge))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(anEdge, V1, V2);
|
||||
Standard_Real fpar, lpar;
|
||||
|
@@ -55,6 +55,7 @@
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Controle
|
||||
@@ -174,6 +175,70 @@ BRepLib_FindSurface::BRepLib_FindSurface(const TopoDS_Shape& S,
|
||||
{
|
||||
Init(S,Tol,OnlyPlane,OnlyClosed);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static void fillParams (const TColStd_Array1OfReal& theKnots,
|
||||
Standard_Integer theDegree,
|
||||
Standard_Real theParMin,
|
||||
Standard_Real theParMax,
|
||||
NCollection_Vector<Standard_Real>& theParams)
|
||||
{
|
||||
Standard_Real aPrevPar = theParMin;
|
||||
theParams.Append (aPrevPar);
|
||||
|
||||
Standard_Integer aNbP = Max (theDegree, 1);
|
||||
|
||||
for (Standard_Integer i = 1;
|
||||
(i < theKnots.Length()) && (theKnots (i) < (theParMax - Precision::PConfusion())); ++i)
|
||||
{
|
||||
if (theKnots (i + 1) < theParMin + Precision::PConfusion())
|
||||
continue;
|
||||
|
||||
Standard_Real aStep = (theKnots (i + 1) - theKnots (i)) / aNbP;
|
||||
for (Standard_Integer k = 1; k <= aNbP ; ++k)
|
||||
{
|
||||
Standard_Real aPar = theKnots (i) + k * aStep;
|
||||
if (aPar > theParMax - Precision::PConfusion())
|
||||
break;
|
||||
|
||||
if (aPar > aPrevPar + Precision::PConfusion())
|
||||
{
|
||||
theParams.Append (aPar);
|
||||
aPrevPar = aPar;
|
||||
}
|
||||
}
|
||||
}
|
||||
theParams.Append (theParMax);
|
||||
}
|
||||
|
||||
static void fillPoints (const BRepAdaptor_Curve& theCurve,
|
||||
const NCollection_Vector<Standard_Real> theParams,
|
||||
TColgp_SequenceOfPnt& thePoints,
|
||||
TColStd_SequenceOfReal& theWeights)
|
||||
{
|
||||
Standard_Real aDistPrev = 0., aDistNext;
|
||||
gp_Pnt aPPrev (theCurve.Value (theParams (0))), aPNext;
|
||||
|
||||
for (Standard_Integer iP = 1; iP <= theParams.Length(); ++iP)
|
||||
{
|
||||
if (iP < theParams.Length())
|
||||
{
|
||||
Standard_Real aParam = theParams (iP);
|
||||
aPNext = theCurve.Value (aParam);
|
||||
aDistNext = aPPrev.Distance (aPNext);
|
||||
}
|
||||
else
|
||||
aDistNext = 0.0;
|
||||
|
||||
thePoints.Append (aPPrev);
|
||||
theWeights.Append (aDistPrev + aDistNext);
|
||||
aDistPrev = aDistNext;
|
||||
aPPrev = aPNext;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
@@ -282,117 +347,57 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
}
|
||||
Standard_Integer iNbPoints=0;
|
||||
|
||||
// Add the points with weights to the sequences
|
||||
// Fill the parameters of the sampling points
|
||||
NCollection_Vector<Standard_Real> aParams;
|
||||
switch (c.GetType())
|
||||
{
|
||||
case GeomAbs_BezierCurve:
|
||||
case GeomAbs_BezierCurve:
|
||||
{
|
||||
// Put all poles for bezier
|
||||
Handle(Geom_BezierCurve) GC = c.Bezier();
|
||||
Standard_Integer iNbPol = GC->NbPoles();
|
||||
Standard_Real tf = GC->FirstParameter();
|
||||
Standard_Real tl = GC->LastParameter();
|
||||
Standard_Real r = (dfUl - dfUf) / (tl - tf);
|
||||
r *= iNbPol;
|
||||
if ( iNbPol < 2 || r < 1.)
|
||||
// Degenerate
|
||||
continue;
|
||||
else
|
||||
{
|
||||
Handle(TColgp_HArray1OfPnt) aPoles = new (TColgp_HArray1OfPnt) (1, iNbPol);
|
||||
GC->Poles(aPoles->ChangeArray1());
|
||||
gp_Pnt aPolePrev = aPoles->Value(1), aPoleNext;
|
||||
Standard_Real dfDistPrev = 0., dfDistNext;
|
||||
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
|
||||
{
|
||||
if (iPol<iNbPol)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+1);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GeomAbs_BSplineCurve:
|
||||
{
|
||||
// Put all poles for bspline
|
||||
Handle(Geom_BSplineCurve) GC = c.BSpline();
|
||||
Standard_Integer iNbPol = GC->NbPoles();
|
||||
Standard_Real tf = GC->FirstParameter();
|
||||
Standard_Real tl = GC->LastParameter();
|
||||
Standard_Real r = (dfUl - dfUf) / (tl - tf);
|
||||
r *= iNbPol;
|
||||
if ( iNbPol < 2 || r < 1.)
|
||||
// Degenerate
|
||||
continue;
|
||||
else
|
||||
{
|
||||
Handle(TColgp_HArray1OfPnt) aPoles = new (TColgp_HArray1OfPnt) (1, iNbPol);
|
||||
GC->Poles(aPoles->ChangeArray1());
|
||||
gp_Pnt aPolePrev = aPoles->Value(1), aPoleNext;
|
||||
Standard_Real dfDistPrev = 0., dfDistNext;
|
||||
for (Standard_Integer iPol=1; iPol<=iNbPol; iPol++)
|
||||
{
|
||||
if (iPol<iNbPol)
|
||||
{
|
||||
aPoleNext = aPoles->Value(iPol+1);
|
||||
dfDistNext = aPolePrev.Distance(aPoleNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPolePrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPolePrev = aPoleNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
TColStd_Array1OfReal aKnots (1, 2);
|
||||
aKnots.SetValue (1, GC->FirstParameter());
|
||||
aKnots.SetValue (2, GC->LastParameter());
|
||||
|
||||
case GeomAbs_Line:
|
||||
case GeomAbs_Circle:
|
||||
case GeomAbs_Ellipse:
|
||||
case GeomAbs_Hyperbola:
|
||||
case GeomAbs_Parabola:
|
||||
// Two points on straight segment, Four points on otheranalitical curves
|
||||
iNbPoints = (c.GetType() == GeomAbs_Line ? 2 : 4);
|
||||
Standard_FALLTHROUGH
|
||||
default:
|
||||
fillParams (aKnots, GC->Degree(), dfUf, dfUl, aParams);
|
||||
break;
|
||||
}
|
||||
case GeomAbs_BSplineCurve:
|
||||
{
|
||||
Handle(Geom_BSplineCurve) GC = c.BSpline();
|
||||
fillParams (GC->Knots(), GC->Degree(), dfUf, dfUl, aParams);
|
||||
break;
|
||||
}
|
||||
case GeomAbs_Line:
|
||||
{
|
||||
// Two points on a straight segment
|
||||
aParams.Append (dfUf);
|
||||
aParams.Append (dfUl);
|
||||
break;
|
||||
}
|
||||
case GeomAbs_Circle:
|
||||
case GeomAbs_Ellipse:
|
||||
case GeomAbs_Hyperbola:
|
||||
case GeomAbs_Parabola:
|
||||
// Four points on other analytical curves
|
||||
iNbPoints = 4;
|
||||
Standard_FALLTHROUGH
|
||||
default:
|
||||
{
|
||||
// Put some points on other curves
|
||||
if (iNbPoints==0)
|
||||
iNbPoints = 15 + c.NbIntervals(GeomAbs_C3);
|
||||
Standard_Real dfDelta = (dfUl-dfUf)/(iNbPoints-1);
|
||||
Standard_Integer iPoint;
|
||||
Standard_Real dfU;
|
||||
gp_Pnt aPointPrev = c.Value(dfUf), aPointNext;
|
||||
Standard_Real dfDistPrev = 0., dfDistNext;
|
||||
for (iPoint=1, dfU=dfUf+dfDelta;
|
||||
iPoint<=iNbPoints;
|
||||
iPoint++, dfU+=dfDelta)
|
||||
{
|
||||
if (iPoint<iNbPoints)
|
||||
{
|
||||
aPointNext = c.Value(dfU);
|
||||
dfDistNext = aPointPrev.Distance(aPointNext);
|
||||
}
|
||||
else
|
||||
dfDistNext = 0.;
|
||||
aPoints.Append (aPointPrev);
|
||||
aWeight.Append (dfDistPrev+dfDistNext);
|
||||
dfDistPrev = dfDistNext;
|
||||
aPointPrev = aPointNext;
|
||||
}
|
||||
} // default:
|
||||
} // switch (c.GetType()) ...
|
||||
} // for (ex.Init(S,TopAbs_EDGE); ex.More() && control; ex.Next()) ...
|
||||
if (iNbPoints == 0)
|
||||
iNbPoints = 15 + c.NbIntervals (GeomAbs_C3);
|
||||
|
||||
TColStd_Array1OfReal aBounds (1, 2);
|
||||
aBounds.SetValue (1, dfUf);
|
||||
aBounds.SetValue (2, dfUl);
|
||||
|
||||
fillParams (aBounds, iNbPoints - 1, dfUf, dfUl, aParams);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the points with weights to the sequences
|
||||
fillPoints (c, aParams, aPoints, aWeight);
|
||||
}
|
||||
|
||||
if (aPoints.Length() < 3) {
|
||||
return;
|
||||
@@ -505,79 +510,33 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// let us be more tolerant (occ415)
|
||||
Standard_Real dfDist = RealLast();
|
||||
Handle(Geom_Plane) aPlane;
|
||||
//
|
||||
if (isSolved) {
|
||||
//Plane normal can have two directions, direction is chosen
|
||||
//according to direction of eigenvector
|
||||
gp_Vec anN(aVec(1), aVec(2), aVec(3));
|
||||
aPlane = new Geom_Plane(aBaryCenter,anN);
|
||||
dfDist = Controle (aPoints, aPlane);
|
||||
}
|
||||
//
|
||||
if (!isSolved || myTolerance < dfDist) {
|
||||
gp_Pnt aFirstPnt=aPoints(1);
|
||||
for (iPoint=2; iPoint<=aPoints.Length(); iPoint++) {
|
||||
gp_Vec aDir(aFirstPnt,aPoints(iPoint));
|
||||
Standard_Real dfSide=aDir.Magnitude();
|
||||
if (dfSide<myTolerance) {
|
||||
continue; // degeneration
|
||||
}
|
||||
for (Standard_Integer iP1=iPoint+1; iP1<=aPoints.Length(); iP1++) {
|
||||
|
||||
gp_Vec aCross = gp_Vec(aFirstPnt,aPoints(iP1)) ^ aDir ;
|
||||
if (!isSolved)
|
||||
return;
|
||||
|
||||
if (aCross.Magnitude() > dfSide*myTolerance) {
|
||||
Handle(Geom_Plane) aPlane2 = new Geom_Plane(aBaryCenter, aCross);
|
||||
Standard_Real dfDist2 = Controle (aPoints, aPlane2);
|
||||
if (dfDist2 < myTolerance) {
|
||||
myTolReached = dfDist2;
|
||||
mySurface = aPlane2;
|
||||
return;
|
||||
}
|
||||
if (dfDist2 < dfDist) {
|
||||
dfDist = dfDist2;
|
||||
aPlane = aPlane2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//XXf
|
||||
//static Standard_Real weakness = 5.0;
|
||||
Standard_Real weakness = 5.0;
|
||||
//XXf
|
||||
if(dfDist <= myTolerance || (dfDist < myTolerance*weakness && Tol<0)) {
|
||||
//XXf
|
||||
//myTolReached = dfDist;
|
||||
//XXt
|
||||
gp_Vec aN (aVec (1), aVec (2), aVec (3));
|
||||
Handle(Geom_Plane) aPlane = new Geom_Plane (aBaryCenter, aN);
|
||||
myTolReached = Controle (aPoints, aPlane);
|
||||
const Standard_Real aWeakness = 5.0;
|
||||
if (myTolReached <= myTolerance || (Tol < 0 && myTolReached < myTolerance * aWeakness))
|
||||
{
|
||||
mySurface = aPlane;
|
||||
//If S is wire, try to orient surface according to orientation of wire.
|
||||
if(S.ShapeType() == TopAbs_WIRE && S.Closed())
|
||||
if (S.ShapeType() == TopAbs_WIRE && S.Closed())
|
||||
{
|
||||
//
|
||||
TopoDS_Wire aW = TopoDS::Wire(S);
|
||||
TopoDS_Face aTmpFace = BRepLib_MakeFace(mySurface, Precision::Confusion());
|
||||
TopoDS_Wire aW = TopoDS::Wire (S);
|
||||
TopoDS_Face aTmpFace = BRepLib_MakeFace (mySurface, Precision::Confusion());
|
||||
BRep_Builder BB;
|
||||
BB.Add(aTmpFace, aW);
|
||||
BRepTopAdaptor_FClass2d FClass(aTmpFace, 0.);
|
||||
if ( FClass.PerformInfinitePoint() == TopAbs_IN )
|
||||
BB.Add (aTmpFace, aW);
|
||||
BRepTopAdaptor_FClass2d FClass (aTmpFace, 0.);
|
||||
if (FClass.PerformInfinitePoint() == TopAbs_IN)
|
||||
{
|
||||
gp_Dir aN = aPlane->Position().Direction();
|
||||
aN.Reverse();
|
||||
mySurface = new Geom_Plane(aPlane->Position().Location(), aN);
|
||||
gp_Dir aNorm = aPlane->Position().Direction();
|
||||
aNorm.Reverse();
|
||||
mySurface = new Geom_Plane (aPlane->Position().Location(), aNorm);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//XXf
|
||||
myTolReached = dfDist;
|
||||
//XXt
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Found
|
||||
|
@@ -1224,9 +1224,9 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection(
|
||||
//function : addTriangle
|
||||
//purpose : Add a triangle based on the given oriented edges into mesh
|
||||
//=======================================================================
|
||||
inline void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
|
||||
const Standard_Boolean (&theEdgesOri)[3],
|
||||
const Standard_Integer (&theNodesId)[3] )
|
||||
void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
|
||||
const Standard_Boolean (&theEdgesOri)[3],
|
||||
const Standard_Integer (&theNodesId)[3] )
|
||||
{
|
||||
Standard_Integer aNewTriangleId =
|
||||
myMeshData->AddElement(BRepMesh_Triangle(theEdgesId,
|
||||
@@ -1890,7 +1890,7 @@ void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger& thePolygon,
|
||||
//function : meshElementaryPolygon
|
||||
//purpose : Triangulation of closed polygon containing only three edges.
|
||||
//=======================================================================
|
||||
inline Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
|
||||
Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
|
||||
const IMeshData::SequenceOfInteger& thePolygon)
|
||||
{
|
||||
Standard_Integer aPolyLen = thePolygon.Length();
|
||||
@@ -2434,8 +2434,9 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
|
||||
p3 = GetVertex( theEdg2.FirstNode() ).Coord();
|
||||
p4 = GetVertex( theEdg2.LastNode() ).Coord();
|
||||
|
||||
Standard_Real aIntParams[2];
|
||||
return BRepMesh_GeomTool::IntSegSeg(p1, p2, p3, p4,
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
|
||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt, aIntParams);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@@ -19,191 +19,6 @@
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
|
||||
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_FaceChecker::Segments) aSegments =
|
||||
new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Real theTolerance)
|
||||
: myMaxLoopSize(M_PI * theTolerance * theTolerance),
|
||||
mySelfSegmentIndex(-1),
|
||||
myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//! Sets working set of segments.
|
||||
void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
gp_Pnt2d aIntPnt;
|
||||
const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment.Point1->XY(), aSegment.Point2->XY(),
|
||||
Standard_False, Standard_False, aIntPnt);
|
||||
|
||||
if (aIntStatus == BRepMesh_GeomTool::Cross)
|
||||
{
|
||||
const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
|
||||
gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
|
||||
|
||||
if (Abs(aAngle) < MaxTangentAngle)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (mySelfSegmentIndex != -1)
|
||||
{
|
||||
gp_XY aPrevVec;
|
||||
Standard_Real aSumS = 0.;
|
||||
const gp_XY& aRefPnt = aIntPnt.Coord();
|
||||
for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
|
||||
gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
|
||||
|
||||
if (aCurVec.SquareModulus() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
if (aPrevVec.SquareModulus() > gp::Resolution())
|
||||
aSumS += aPrevVec ^ aCurVec;
|
||||
|
||||
aPrevVec = aCurVec;
|
||||
}
|
||||
|
||||
if (Abs(aSumS / 2.) < myMaxLoopSize)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Standard_Real myMaxLoopSize;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_FaceChecker::Segments) mySegments;
|
||||
const BRepMesh_FaceChecker::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
@@ -211,8 +26,7 @@ namespace
|
||||
BRepMesh_FaceChecker::BRepMesh_FaceChecker(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace(theFace),
|
||||
myParameters(theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,50 +44,39 @@ BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceChecker::Perform()
|
||||
{
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
collectSegments();
|
||||
|
||||
myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
|
||||
collectResult();
|
||||
|
||||
myWiresBndBoxTree.Nullify();
|
||||
myWiresSegments.Nullify();
|
||||
myWiresBndBoxTree .Nullify();
|
||||
myWiresSegments .Nullify();
|
||||
myWiresIntersectingEdges.Nullify();
|
||||
return myIntersectingEdges->IsEmpty();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
|
||||
myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex);
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments ->Value (theWireIndex);
|
||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
|
||||
|
||||
// TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
|
||||
BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_False);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
@@ -287,7 +90,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
}
|
||||
|
@@ -16,49 +16,18 @@
|
||||
#ifndef _BRepMesh_FaceChecker_HeaderFile
|
||||
#define _BRepMesh_FaceChecker_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class checking wires of target face for self-intersections.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones. All collisions are registerd and returned as result of check.
|
||||
class BRepMesh_FaceChecker : public Standard_Transient
|
||||
class BRepMesh_FaceChecker : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
gp_Pnt2d* Point1; // \ Use explicit pointers to points instead of accessing
|
||||
gp_Pnt2d* Point2; // / using indices.
|
||||
|
||||
Segment()
|
||||
: Point1(NULL)
|
||||
, Point2(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
gp_Pnt2d* thePoint2)
|
||||
: EdgePtr(theEdgePtr)
|
||||
, Point1(thePoint1)
|
||||
, Point2(thePoint2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::MapOfIEdgePtr)> > ArrayOfMapOfIEdgePtr;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
@@ -82,19 +51,10 @@ public: //! @name mesher API
|
||||
perform(theWireIndex);
|
||||
}
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient)
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
//! Collects intersecting edges.
|
||||
void collectResult();
|
||||
|
||||
@@ -109,11 +69,6 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
Handle(ArrayOfMapOfIEdgePtr) myWiresIntersectingEdges;
|
||||
Handle(IMeshData::MapOfIEdgePtr) myIntersectingEdges;
|
||||
|
||||
|
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
100
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.cxx
Normal file
@@ -0,0 +1,100 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: BRepMesh_SegmentedFace (theFace, theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_FaceIntersectionsSplitter::~BRepMesh_FaceIntersectionsSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::Perform()
|
||||
{
|
||||
for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
Standard_Boolean isSplit = Standard_True;
|
||||
while (isSplit)
|
||||
{
|
||||
collectSegments();
|
||||
|
||||
isSplit = perform(aWireIt);
|
||||
|
||||
myWiresSegments .Nullify();
|
||||
myWiresBndBoxTree.Nullify();
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceIntersectionsSplitter::perform(
|
||||
const Standard_Integer theWireIndex)
|
||||
{
|
||||
const Handle(Segments)& aSegments1 = myWiresSegments->Value (theWireIndex);
|
||||
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector aSelector (Standard_True);
|
||||
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
|
||||
{
|
||||
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
|
||||
const Handle(Segments)& aSegments2 = myWiresSegments ->Value(aWireIt);
|
||||
|
||||
aSelector.SetSegments(aSegments2);
|
||||
for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
|
||||
aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
|
||||
if (aBndBoxTree2->Select(aSelector) != 0)
|
||||
{
|
||||
const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
|
||||
const BRepMesh_SegmentedFace::VectorOfIntersectionParams& aIntParams = aSelector.IntParams();
|
||||
for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
|
||||
|
||||
//aIntersections->Add(aSegment1.EdgePtr);
|
||||
//aIntersections->Add(aSegment2.EdgePtr);
|
||||
}
|
||||
|
||||
//return Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
55
src/BRepMesh/BRepMesh_FaceIntersectionsSplitter.hxx
Normal file
@@ -0,0 +1,55 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
#define _BRepMesh_FaceIntersectionsSplitter_HeaderFile
|
||||
|
||||
#include <BRepMesh_SegmentedFace.hxx>
|
||||
|
||||
//! Auxiliary class splitting intersecting segments of wires of target face.
|
||||
//! Explodes wires of discrete face on sets of segments using tessellation
|
||||
//! data stored in model. Each segment is then checked for intersection with
|
||||
//! other ones and split on intersection point.
|
||||
class BRepMesh_FaceIntersectionsSplitter : public BRepMesh_SegmentedFace
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_FaceIntersectionsSplitter(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_FaceIntersectionsSplitter();
|
||||
|
||||
//! Performs split of intersecting segments of wires of the face.
|
||||
//! @return True if there is no intersection, False elsewhere.
|
||||
Standard_EXPORT Standard_Boolean Perform();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceIntersectionsSplitter, BRepMesh_SegmentedFace)
|
||||
|
||||
private:
|
||||
|
||||
//! Splits wire with the given index at first intersection point with others.
|
||||
Standard_Boolean perform(const Standard_Integer theWireIndex);
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter (const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
|
||||
void operator=(const BRepMesh_FaceIntersectionsSplitter& theOther);
|
||||
};
|
||||
|
||||
#endif
|
@@ -333,7 +333,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt)
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2])
|
||||
{
|
||||
Standard_Integer aPointHash[] = {
|
||||
classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
|
||||
@@ -393,9 +394,8 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
else if ( aPosHash == 2 )
|
||||
return BRepMesh_GeomTool::Glued;
|
||||
|
||||
Standard_Real aParam[2];
|
||||
IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
|
||||
theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), theParamOnSegment);
|
||||
|
||||
if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
@@ -416,7 +416,7 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
|
||||
const Standard_Real aEndPrec = 1 - aPrec;
|
||||
for (Standard_Integer i = 0; i < 2; ++i)
|
||||
{
|
||||
if(aParam[i] < aPrec || aParam[i] > aEndPrec )
|
||||
if(theParamOnSegment[i] < aPrec || theParamOnSegment[i] > aEndPrec )
|
||||
return BRepMesh_GeomTool::NoIntersection;
|
||||
}
|
||||
|
||||
|
@@ -194,7 +194,8 @@ public: //! @name static API
|
||||
const gp_XY& theEndPnt2,
|
||||
const Standard_Boolean isConsiderEndPointTouch,
|
||||
const Standard_Boolean isConsiderPointOnSegment,
|
||||
gp_Pnt2d& theIntPnt);
|
||||
gp_Pnt2d& theIntPnt,
|
||||
Standard_Real (&theParamOnSegment)[2]);
|
||||
|
||||
//! Compute deflection of the given segment.
|
||||
static Standard_Real SquareDeflectionOfSegment(
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <BRepMesh_Deflection.hxx>
|
||||
#include <BRepMesh_ShapeTool.hxx>
|
||||
#include <BRepMesh_FaceChecker.hxx>
|
||||
#include <BRepMesh_FaceIntersectionsSplitter.hxx>
|
||||
#include <BRepMesh_EdgeDiscret.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
@@ -150,7 +151,12 @@ Standard_Boolean BRepMesh_ModelHealer::performInternal(
|
||||
{
|
||||
const IMeshData::IFaceHandle aDFace = aFaceIt.Key();
|
||||
aDFace->SetStatus(IMeshData_SelfIntersectingWire);
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
|
||||
BRepMesh_FaceIntersectionsSplitter aSplitter (aDFace, myParameters);
|
||||
if (!aSplitter.Perform())
|
||||
{
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
204
src/BRepMesh/BRepMesh_SegmentedFace.cxx
Normal file
@@ -0,0 +1,204 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 <BRepMesh_SegmentedFace.hxx>
|
||||
#include <IMeshData_Wire.hxx>
|
||||
#include <IMeshData_Edge.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Functor to be used to fill segments and bounding box tree in parallel.
|
||||
class SegmentsFiller
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& theWiresSegments,
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& theWiresBndBoxTree)
|
||||
: myDFace(theDFace),
|
||||
myWiresSegments(theWiresSegments),
|
||||
myWiresBndBoxTree(theWiresBndBoxTree)
|
||||
{
|
||||
myWiresSegments = new BRepMesh_SegmentedFace::ArrayOfSegments (0, myDFace->WiresNb() - 1);
|
||||
myWiresBndBoxTree = new BRepMesh_SegmentedFace::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
|
||||
}
|
||||
|
||||
//! Performs initialization of wire with the given index.
|
||||
void operator()(const Standard_Integer theWireIndex) const
|
||||
{
|
||||
const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc1 = new NCollection_IncAllocator();
|
||||
|
||||
Handle(BRepMesh_SegmentedFace::Segments) aSegments =
|
||||
new BRepMesh_SegmentedFace::Segments(aDWire->EdgesNb(), aTmpAlloc1);
|
||||
Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
|
||||
|
||||
myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
|
||||
myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTmpAlloc2 = new NCollection_IncAllocator();
|
||||
IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
|
||||
|
||||
for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
|
||||
{
|
||||
// TODO: check 2d wire for consistency.
|
||||
|
||||
const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
|
||||
|
||||
for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
|
||||
{
|
||||
gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
|
||||
gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
|
||||
|
||||
Bnd_Box2d aBox;
|
||||
aBox.Add(aPnt1);
|
||||
aBox.Add(aPnt2);
|
||||
aBox.Enlarge(Precision::Confusion());
|
||||
|
||||
aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
|
||||
aSegments->Append(BRepMesh_SegmentedFace::Segment(
|
||||
aDEdge, aPCurve.get(),
|
||||
&aPnt1, aPointIt - 1,
|
||||
&aPnt2, aPointIt));
|
||||
}
|
||||
}
|
||||
|
||||
aBndBoxTreeFiller.Fill();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SegmentsFiller (const SegmentsFiller& theOther);
|
||||
|
||||
void operator=(const SegmentsFiller& theOther);
|
||||
|
||||
private:
|
||||
|
||||
const IMeshData::IFaceHandle& myDFace;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfSegments)& myWiresSegments;
|
||||
Handle(BRepMesh_SegmentedFace::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BndBox2dTreeSelector::BndBox2dTreeSelector(
|
||||
const Standard_Boolean isCollectIntersectionParams)
|
||||
: myCollectIntersectionParams (isCollectIntersectionParams)
|
||||
, mySelfSegmentIndex(-1)
|
||||
, myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reset
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reset(
|
||||
const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex)
|
||||
{
|
||||
myIndices .Clear();
|
||||
myIntParams.Clear();
|
||||
|
||||
mySelfSegmentIndex = theSelfSegmentIndex;
|
||||
mySegment = theSegment;
|
||||
|
||||
myBox.SetVoid();
|
||||
myBox.Add(*mySegment->Point1);
|
||||
myBox.Add(*mySegment->Point2);
|
||||
myBox.Enlarge(Precision::Confusion());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reject
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Reject(
|
||||
const Bnd_Box2d& theBox) const
|
||||
{
|
||||
return myBox.IsOut(theBox);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Accept
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_SegmentedFace::BndBox2dTreeSelector::Accept(
|
||||
const Standard_Integer& theSegmentIndex)
|
||||
{
|
||||
const BRepMesh_SegmentedFace::Segment& aSegment = mySegments->Value(theSegmentIndex);
|
||||
|
||||
IntersectionParams aIntNode;
|
||||
aIntNode.Type = BRepMesh_GeomTool::IntSegSeg(
|
||||
mySegment->Point1->XY(), mySegment->Point2->XY(),
|
||||
aSegment .Point1->XY(), aSegment .Point2->XY(),
|
||||
Standard_False, Standard_False,
|
||||
aIntNode.Point, aIntNode.Params);
|
||||
|
||||
if (aIntNode.Type == BRepMesh_GeomTool::Cross ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::PointOnSegment ||
|
||||
aIntNode.Type == BRepMesh_GeomTool::Glued)
|
||||
{
|
||||
|
||||
myIndices.Append(theSegmentIndex);
|
||||
|
||||
if (myCollectIntersectionParams)
|
||||
{
|
||||
myIntParams.Append(aIntNode);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::BRepMesh_SegmentedFace(
|
||||
const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
: myDFace (theFace),
|
||||
myParameters(theParameters)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Destructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepMesh_SegmentedFace::~BRepMesh_SegmentedFace()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : collectSegments
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_SegmentedFace::collectSegments()
|
||||
{
|
||||
SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
|
||||
OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
|
||||
}
|
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
169
src/BRepMesh/BRepMesh_SegmentedFace.hxx
Normal file
@@ -0,0 +1,169 @@
|
||||
// Created on: 2016-07-04
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
// Created by: Oleg AGASHIN
|
||||
//
|
||||
// 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 _BRepMesh_SegmentedFace_HeaderFile
|
||||
#define _BRepMesh_SegmentedFace_HeaderFile
|
||||
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <IMeshData_Face.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepMesh_GeomTool.hxx>
|
||||
|
||||
//! Auxiliary class providing common functionality for exploding wires of
|
||||
//! discrete face on sets of segments using tessellation data stored in model.
|
||||
class BRepMesh_SegmentedFace : public Standard_Transient
|
||||
{
|
||||
public: //! @name mesher API
|
||||
|
||||
//! Identifies segment inside face.
|
||||
//! Uses explicit pointers to points instead of accessing using indices.
|
||||
struct Segment
|
||||
{
|
||||
IMeshData::IEdgePtr EdgePtr;
|
||||
IMeshData::IPCurvePtr PCurvePtr;
|
||||
gp_Pnt2d* Point1;
|
||||
Standard_Integer Param1;
|
||||
gp_Pnt2d* Point2;
|
||||
Standard_Integer Param2;
|
||||
|
||||
Segment()
|
||||
: EdgePtr (NULL)
|
||||
, PCurvePtr(NULL)
|
||||
, Point1 (NULL)
|
||||
, Param1 (0)
|
||||
, Point2 (NULL)
|
||||
, Param2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const IMeshData::IEdgePtr& theEdgePtr,
|
||||
const IMeshData::IPCurvePtr& thePCurvePtr,
|
||||
gp_Pnt2d* thePoint1,
|
||||
const Standard_Integer theParam1,
|
||||
gp_Pnt2d* thePoint2,
|
||||
const Standard_Integer theParam2)
|
||||
: EdgePtr (theEdgePtr)
|
||||
, PCurvePtr(thePCurvePtr)
|
||||
, Point1 (thePoint1)
|
||||
, Param1 (theParam1)
|
||||
, Point2 (thePoint2)
|
||||
, Param2 (theParam2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! Keeps parameters of intersection of two segments.
|
||||
//! Params are in range relative to distance between points of corresponding segment.
|
||||
struct IntersectionParams
|
||||
{
|
||||
BRepMesh_GeomTool::IntFlag Type;
|
||||
gp_Pnt2d Point;
|
||||
Standard_Real Params[2];
|
||||
};
|
||||
|
||||
typedef NCollection_Vector<IntersectionParams> VectorOfIntersectionParams;
|
||||
typedef NCollection_Shared<NCollection_Vector<Segment> > Segments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> > ArrayOfSegments;
|
||||
typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> > ArrayOfBndBoxTree;
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Standard_EXPORT BRepMesh_SegmentedFace(const IMeshData::IFaceHandle& theFace,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Destructor
|
||||
Standard_EXPORT virtual ~BRepMesh_SegmentedFace();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_SegmentedFace, Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns True in case if check can be performed in parallel mode.
|
||||
inline Standard_Boolean isParallel() const
|
||||
{
|
||||
return (myParameters.InParallel && myDFace->WiresNb() > 1);
|
||||
}
|
||||
|
||||
//! Collects face segments.
|
||||
void collectSegments();
|
||||
|
||||
private:
|
||||
|
||||
BRepMesh_SegmentedFace (const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
void operator=(const BRepMesh_SegmentedFace& theOther);
|
||||
|
||||
protected:
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
BndBox2dTreeSelector(const Standard_Boolean isCollectIntersectionParams);
|
||||
|
||||
//! Sets working set of segments.
|
||||
inline void SetSegments(const Handle(BRepMesh_SegmentedFace::Segments)& theSegments)
|
||||
{
|
||||
mySegments = theSegments;
|
||||
}
|
||||
|
||||
//! Returns indices of intersecting segments.
|
||||
inline const IMeshData::VectorOfInteger& Indices() const
|
||||
{
|
||||
return myIndices;
|
||||
}
|
||||
|
||||
//! Returns intersection parameters.
|
||||
inline const BRepMesh_SegmentedFace::VectorOfIntersectionParams& IntParams() const
|
||||
{
|
||||
return myIntParams;
|
||||
}
|
||||
|
||||
//! Resets current selector.
|
||||
void Reset(const BRepMesh_SegmentedFace::Segment* theSegment,
|
||||
const Standard_Integer theSelfSegmentIndex);
|
||||
|
||||
//! Indicates should the given box be rejected or not.
|
||||
virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const;
|
||||
|
||||
//! Accepts segment with the given index in case if it fits conditions.
|
||||
virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex);
|
||||
|
||||
private:
|
||||
|
||||
Standard_Boolean myCollectIntersectionParams;
|
||||
Standard_Integer mySelfSegmentIndex;
|
||||
Handle(BRepMesh_SegmentedFace::Segments) mySegments;
|
||||
const BRepMesh_SegmentedFace::Segment* mySegment;
|
||||
Bnd_Box2d myBox;
|
||||
IMeshData::VectorOfInteger myIndices;
|
||||
BRepMesh_SegmentedFace::VectorOfIntersectionParams myIntParams;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
IMeshData::IFaceHandle myDFace;
|
||||
const IMeshTools_Parameters& myParameters;
|
||||
|
||||
Handle(ArrayOfSegments) myWiresSegments;
|
||||
Handle(ArrayOfBndBoxTree) myWiresBndBoxTree;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -41,6 +41,8 @@ BRepMesh_EdgeTessellationExtractor.cxx
|
||||
BRepMesh_EdgeTessellationExtractor.hxx
|
||||
BRepMesh_FaceChecker.cxx
|
||||
BRepMesh_FaceChecker.hxx
|
||||
BRepMesh_FaceIntersectionsSplitter.cxx
|
||||
BRepMesh_FaceIntersectionsSplitter.hxx
|
||||
BRepMesh_FaceDiscret.cxx
|
||||
BRepMesh_FaceDiscret.hxx
|
||||
BRepMesh_FactoryError.hxx
|
||||
@@ -68,6 +70,8 @@ BRepMesh_OrientedEdge.hxx
|
||||
BRepMesh_PairOfIndex.hxx
|
||||
BRepMesh_PluginEntryType.hxx
|
||||
BRepMesh_PluginMacro.hxx
|
||||
BRepMesh_SegmentedFace.cxx
|
||||
BRepMesh_SegmentedFace.hxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.cxx
|
||||
BRepMesh_SelectorOfDataStructureOfDelaun.hxx
|
||||
BRepMesh_ShapeTool.cxx
|
||||
|
@@ -44,16 +44,8 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <ChFi3d.hxx>
|
||||
|
||||
//
|
||||
static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
|
||||
//
|
||||
static BRepOffset_Type DefineConnectType(const TopoDS_Edge& E,
|
||||
const TopoDS_Face& F1,
|
||||
const TopoDS_Face& F2,
|
||||
const Standard_Real SinTol,
|
||||
const Standard_Boolean CorrectPoint);
|
||||
//
|
||||
static void CorrectOrientationOfTangent(gp_Vec& TangVec,
|
||||
const TopoDS_Vertex& aVertex,
|
||||
const TopoDS_Edge& anEdge)
|
||||
@@ -105,16 +97,17 @@ static void EdgeAnalyse(const TopoDS_Edge& E,
|
||||
// Tangent if the regularity is at least G1.
|
||||
if (BRep_Tool::HasContinuity(E,F1,F2)) {
|
||||
if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
|
||||
I.Type(BRepOffset_Tangent);
|
||||
I.Type(ChFiDS_Tangential);
|
||||
LI.Append(I);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//
|
||||
BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
|
||||
if(aType != BRepOffset_Tangent)
|
||||
ChFiDS_TypeOfConcavity aType = ChFi3d::DefineConnectType(E, F1, F2,
|
||||
SinTol, Standard_False);
|
||||
if(aType != ChFiDS_Tangential)
|
||||
{
|
||||
aType = DefineConnectType(E, F1, F2, SinTol, Standard_True);
|
||||
aType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_True);
|
||||
}
|
||||
I.Type(aType);
|
||||
LI.Append(I);
|
||||
@@ -181,10 +174,10 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
|
||||
Standard_Real U1,U2;
|
||||
const TopoDS_Face& F = TopoDS::Face(L.First());
|
||||
BRep_Tool::Range(E,F,U1,U2);
|
||||
BRepOffset_Interval Inter(U1,U2,BRepOffset_Other);
|
||||
BRepOffset_Interval Inter(U1,U2,ChFiDS_Other);
|
||||
|
||||
if (! BRepTools::IsReallyClosed(E,F)) {
|
||||
Inter.Type(BRepOffset_FreeBoundary);
|
||||
Inter.Type(ChFiDS_FreeBound);
|
||||
}
|
||||
mapEdgeType(E).Append(Inter);
|
||||
}
|
||||
@@ -233,7 +226,7 @@ const
|
||||
//=======================================================================
|
||||
|
||||
void BRepOffset_Analyse::Edges(const TopoDS_Vertex& V,
|
||||
const BRepOffset_Type T,
|
||||
const ChFiDS_TypeOfConcavity T,
|
||||
TopTools_ListOfShape& LE)
|
||||
const
|
||||
{
|
||||
@@ -263,7 +256,7 @@ const
|
||||
//=======================================================================
|
||||
|
||||
void BRepOffset_Analyse::Edges(const TopoDS_Face& F,
|
||||
const BRepOffset_Type T,
|
||||
const ChFiDS_TypeOfConcavity T,
|
||||
TopTools_ListOfShape& LE)
|
||||
const
|
||||
{
|
||||
@@ -350,8 +343,8 @@ const TopTools_ListOfShape& BRepOffset_Analyse::Ancestors
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
const BRepOffset_Type T ) const
|
||||
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
const ChFiDS_TypeOfConcavity T ) const
|
||||
{
|
||||
List.Clear();
|
||||
BRep_Builder B;
|
||||
@@ -377,9 +370,9 @@ void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
const BRepOffset_Type T1,
|
||||
const BRepOffset_Type T2) const
|
||||
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
const ChFiDS_TypeOfConcavity T1,
|
||||
const ChFiDS_TypeOfConcavity T2) const
|
||||
{
|
||||
List.Clear();
|
||||
BRep_Builder B;
|
||||
@@ -409,7 +402,7 @@ void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
|
||||
void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
|
||||
TopoDS_Compound& Co,
|
||||
TopTools_MapOfShape& Map,
|
||||
const BRepOffset_Type T) const
|
||||
const ChFiDS_TypeOfConcavity T) const
|
||||
{
|
||||
BRep_Builder B;
|
||||
TopExp_Explorer exp(Face,TopAbs_EDGE);
|
||||
@@ -439,8 +432,8 @@ void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
|
||||
void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
|
||||
TopoDS_Compound& Co,
|
||||
TopTools_MapOfShape& Map,
|
||||
const BRepOffset_Type T1,
|
||||
const BRepOffset_Type T2) const
|
||||
const ChFiDS_TypeOfConcavity T1,
|
||||
const ChFiDS_TypeOfConcavity T2) const
|
||||
{
|
||||
BRep_Builder B;
|
||||
TopExp_Explorer exp(Face,TopAbs_EDGE);
|
||||
@@ -464,135 +457,3 @@ void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Correct2dPoint
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d)
|
||||
{
|
||||
BRepAdaptor_Surface aBAS(theF, Standard_False);
|
||||
if (aBAS.GetType() < GeomAbs_BezierSurface) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
const Standard_Real coeff = 0.01;
|
||||
Standard_Real eps;
|
||||
Standard_Real u1, u2, v1, v2;
|
||||
//
|
||||
aBAS.Initialize(theF, Standard_True);
|
||||
u1 = aBAS.FirstUParameter();
|
||||
u2 = aBAS.LastUParameter();
|
||||
v1 = aBAS.FirstVParameter();
|
||||
v2 = aBAS.LastVParameter();
|
||||
if (!(Precision::IsInfinite(u1) || Precision::IsInfinite(u2)))
|
||||
{
|
||||
eps = Max(coeff*(u2 - u1), Precision::PConfusion());
|
||||
if (Abs(theP2d.X() - u1) < eps)
|
||||
{
|
||||
theP2d.SetX(u1 + eps);
|
||||
}
|
||||
if (Abs(theP2d.X() - u2) < eps)
|
||||
{
|
||||
theP2d.SetX(u2 - eps);
|
||||
}
|
||||
}
|
||||
if (!(Precision::IsInfinite(v1) || Precision::IsInfinite(v2)))
|
||||
{
|
||||
eps = Max(coeff*(v2 - v1), Precision::PConfusion());
|
||||
if (Abs(theP2d.Y() - v1) < eps)
|
||||
{
|
||||
theP2d.SetY(v1 + eps);
|
||||
}
|
||||
if (Abs(theP2d.Y() - v2) < eps)
|
||||
{
|
||||
theP2d.SetY(v2 - eps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefineConnectType
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
BRepOffset_Type DefineConnectType(const TopoDS_Edge& E,
|
||||
const TopoDS_Face& F1,
|
||||
const TopoDS_Face& F2,
|
||||
const Standard_Real SinTol,
|
||||
const Standard_Boolean CorrectPoint)
|
||||
{
|
||||
TopLoc_Location L;
|
||||
Standard_Real f,l;
|
||||
|
||||
const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1);
|
||||
const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2);
|
||||
//
|
||||
Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
|
||||
Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
|
||||
|
||||
BRepAdaptor_Curve C(E);
|
||||
f = C.FirstParameter();
|
||||
l = C.LastParameter();
|
||||
//
|
||||
Standard_Real ParOnC = 0.5*(f+l);
|
||||
gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation());
|
||||
if (T1.SquareMagnitude() > gp::Resolution()) {
|
||||
T1.Normalize();
|
||||
}
|
||||
|
||||
if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) {
|
||||
T1.Reverse();
|
||||
}
|
||||
if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse();
|
||||
|
||||
gp_Pnt2d P = C1->Value(ParOnC);
|
||||
gp_Pnt P3;
|
||||
gp_Vec D1U,D1V;
|
||||
|
||||
if(CorrectPoint)
|
||||
Correct2dPoint(F1, P);
|
||||
//
|
||||
S1->D1(P.X(),P.Y(),P3,D1U,D1V);
|
||||
gp_Vec DN1(D1U^D1V);
|
||||
if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
|
||||
|
||||
P = C2->Value(ParOnC);
|
||||
if(CorrectPoint)
|
||||
Correct2dPoint(F2, P);
|
||||
S2->D1(P.X(),P.Y(),P3,D1U,D1V);
|
||||
gp_Vec DN2(D1U^D1V);
|
||||
if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
|
||||
|
||||
DN1.Normalize();
|
||||
DN2.Normalize();
|
||||
|
||||
gp_Vec ProVec = DN1^DN2;
|
||||
Standard_Real NormProVec = ProVec.Magnitude();
|
||||
|
||||
if (Abs(NormProVec) < SinTol) {
|
||||
// plane
|
||||
if (DN1.Dot(DN2) > 0) {
|
||||
//Tangent
|
||||
return BRepOffset_Tangent;
|
||||
}
|
||||
else {
|
||||
//Mixed not finished!
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout <<" faces locally mixed"<<std::endl;
|
||||
#endif
|
||||
return BRepOffset_Convex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (NormProVec > gp::Resolution())
|
||||
ProVec.Normalize();
|
||||
Standard_Real Prod = T1.Dot(DN1^DN2);
|
||||
if (Prod > 0.) {
|
||||
//
|
||||
return BRepOffset_Convex;
|
||||
}
|
||||
else {
|
||||
//reenters
|
||||
return BRepOffset_Concave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <BRepOffset_ListOfInterval.hxx>
|
||||
#include <BRepOffset_Type.hxx>
|
||||
#include <ChFiDS_TypeOfConcavity.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
class TopoDS_Shape;
|
||||
@@ -60,15 +60,21 @@ public:
|
||||
|
||||
//! Stores in <L> all the edges of Type <T>
|
||||
//! on the vertex <V>.
|
||||
Standard_EXPORT void Edges (const TopoDS_Vertex& V, const BRepOffset_Type T, TopTools_ListOfShape& L) const;
|
||||
Standard_EXPORT void Edges (const TopoDS_Vertex& V,
|
||||
const ChFiDS_TypeOfConcavity T,
|
||||
TopTools_ListOfShape& L) const;
|
||||
|
||||
//! Stores in <L> all the edges of Type <T>
|
||||
//! on the face <F>.
|
||||
Standard_EXPORT void Edges (const TopoDS_Face& F, const BRepOffset_Type T, TopTools_ListOfShape& L) const;
|
||||
Standard_EXPORT void Edges (const TopoDS_Face& F,
|
||||
const ChFiDS_TypeOfConcavity T,
|
||||
TopTools_ListOfShape& L) const;
|
||||
|
||||
//! set in <Edges> all the Edges of <Shape> which are
|
||||
//! tangent to <Edge> at the vertex <Vertex>.
|
||||
Standard_EXPORT void TangentEdges (const TopoDS_Edge& Edge, const TopoDS_Vertex& Vertex, TopTools_ListOfShape& Edges) const;
|
||||
Standard_EXPORT void TangentEdges (const TopoDS_Edge& Edge,
|
||||
const TopoDS_Vertex& Vertex,
|
||||
TopTools_ListOfShape& Edges) const;
|
||||
|
||||
Standard_EXPORT Standard_Boolean HasAncestor (const TopoDS_Shape& S) const;
|
||||
|
||||
@@ -76,19 +82,29 @@ public:
|
||||
|
||||
//! Explode in compounds of faces where
|
||||
//! all the connex edges are of type <Side>
|
||||
Standard_EXPORT void Explode (TopTools_ListOfShape& L, const BRepOffset_Type Type) const;
|
||||
Standard_EXPORT void Explode (TopTools_ListOfShape& L,
|
||||
const ChFiDS_TypeOfConcavity Type) const;
|
||||
|
||||
//! Explode in compounds of faces where
|
||||
//! all the connex edges are of type <Side1> or <Side2>
|
||||
Standard_EXPORT void Explode (TopTools_ListOfShape& L, const BRepOffset_Type Type1, const BRepOffset_Type Type2) const;
|
||||
Standard_EXPORT void Explode (TopTools_ListOfShape& L,
|
||||
const ChFiDS_TypeOfConcavity Type1,
|
||||
const ChFiDS_TypeOfConcavity Type2) const;
|
||||
|
||||
//! Add in <CO> the faces of the shell containing <Face>
|
||||
//! where all the connex edges are of type <Side>.
|
||||
Standard_EXPORT void AddFaces (const TopoDS_Face& Face, TopoDS_Compound& Co, TopTools_MapOfShape& Map, const BRepOffset_Type Type) const;
|
||||
Standard_EXPORT void AddFaces (const TopoDS_Face& Face,
|
||||
TopoDS_Compound& Co,
|
||||
TopTools_MapOfShape& Map,
|
||||
const ChFiDS_TypeOfConcavity Type) const;
|
||||
|
||||
//! Add in <CO> the faces of the shell containing <Face>
|
||||
//! where all the connex edges are of type <Side1> or <Side2>.
|
||||
Standard_EXPORT void AddFaces (const TopoDS_Face& Face, TopoDS_Compound& Co, TopTools_MapOfShape& Map, const BRepOffset_Type Type1, const BRepOffset_Type Type2) const;
|
||||
Standard_EXPORT void AddFaces (const TopoDS_Face& Face,
|
||||
TopoDS_Compound& Co,
|
||||
TopTools_MapOfShape& Map,
|
||||
const ChFiDS_TypeOfConcavity Type1,
|
||||
const ChFiDS_TypeOfConcavity Type2) const;
|
||||
|
||||
|
||||
|
||||
|
@@ -253,8 +253,8 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
|
||||
const BRepOffset_Analyse& Analyse,
|
||||
const BRepAlgo_Image& InitOffsetFace)
|
||||
{
|
||||
BRepOffset_Type OT = BRepOffset_Concave;
|
||||
if (mySide == TopAbs_OUT) OT = BRepOffset_Convex;
|
||||
ChFiDS_TypeOfConcavity OT = ChFiDS_Concave;
|
||||
if (mySide == TopAbs_OUT) OT = ChFiDS_Convex;
|
||||
TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE);
|
||||
TopTools_ListOfShape LInt1,LInt2;
|
||||
TopoDS_Face F1,F2;
|
||||
@@ -349,7 +349,7 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
|
||||
// to the tube or if E2 is not a tangent edge.
|
||||
//-------------------------------------------------------
|
||||
const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
|
||||
if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
|
||||
if (!L.IsEmpty() && L.First().Type() == ChFiDS_Tangential) {
|
||||
continue;
|
||||
}
|
||||
const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2);
|
||||
@@ -511,13 +511,13 @@ void BRepOffset_Inter3d::ConnexIntByInt
|
||||
continue;
|
||||
}
|
||||
//
|
||||
BRepOffset_Type OT = L.First().Type();
|
||||
if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
|
||||
ChFiDS_TypeOfConcavity OT = L.First().Type();
|
||||
if (OT != ChFiDS_Convex && OT != ChFiDS_Concave) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
|
||||
else CurSide = TopAbs_OUT;
|
||||
if (OT == ChFiDS_Concave) CurSide = TopAbs_IN;
|
||||
else CurSide = TopAbs_OUT;
|
||||
//-----------------------------------------------------------
|
||||
// edge is of the proper type, return adjacent faces.
|
||||
//-----------------------------------------------------------
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user