macad.managed解析interop,occextentions,occhelper

2024-04-07 18:20

本文主要是介绍macad.managed解析interop,occextentions,occhelper,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.

#include "ManagedPCH.h"// 引入System命名空间
using namespace System;// 定义Macad命名空间下的Interop子命名空间
namespace Macad {namespace Interop{// 定义异常信息结构体public ref struct ExceptionInfo{public:// 异常来源枚举enum class ExceptionSource{OCCT, // Open CASCADE Technology异常STL   // 标准模板库异常};//--------------------------------------------------------------------------------------------------// 异常来源属性property ExceptionSource Source {ExceptionSource get() { return _Source; }}//--------------------------------------------------------------------------------------------------// 异常消息属性property String^ Message{String^ get() { return _Message; }}//--------------------------------------------------------------------------------------------------internal:// 内部构造函数,用于创建ExceptionInfo对象ExceptionInfo(ExceptionSource source, const char * message){_Source = source;_Message = gcnew String(message);}//--------------------------------------------------------------------------------------------------private:ExceptionSource _Source; // 异常来源String^ _Message;       // 异常消息};//--------------------------------------------------------------------------------------------------// 异常辅助类public ref class ExceptionHelper{static const int CppExceptionCode = 0xe06d7363; // C++异常代码//--------------------------------------------------------------------------------------------------public:// 获取本地异常信息static ExceptionInfo^ GetNativeExceptionInfo(IntPtr^ ptr){try {auto eptr = (EXCEPTION_POINTERS*)(ptr->ToPointer()); // 获取异常指针if (eptr->ExceptionRecord->ExceptionCode == CppExceptionCode){const EXCEPTION_RECORD & er = *eptr->ExceptionRecord; // 获取异常记录void* object = (void*)eptr->ExceptionRecord->ExceptionInformation[1]; // 获取异常对象指针auto occtException = dynamic_cast<::Standard_Failure*>(reinterpret_cast<Standard_Transient*>(object)); // 检查是否是OCCT异常if (occtException != nullptr){const char* message = occtException->GetMessageString(); // 获取OCCT异常消息if (message == nullptr || strlen(message) == 0){message = occtException->DynamicType()->Name(); // 若消息为空,则获取异常类型名称}return gcnew ExceptionInfo(ExceptionInfo::ExceptionSource::OCCT, message); // 返回OCCT异常信息}auto stdException = dynamic_cast<std::exception*>(reinterpret_cast<std::exception*>(object)); // 检查是否是STL异常if (stdException != nullptr){return gcnew ExceptionInfo(ExceptionInfo::ExceptionSource::STL, stdException->what()); // 返回STL异常信息}}return nullptr; // 如果不是C++异常,返回空指针}catch (...) // 捕获所有异常{return nullptr; // 发生异常时返回空指针}}//--------------------------------------------------------------------------------------------------// 抛出OCCT异常static void RaiseOcctException(){::Standard_Failure::Raise("This is a OCCT exception of type Standard_Failure.");}//--------------------------------------------------------------------------------------------------// 抛出STL异常static void RaiseStlException(){throw std::exception("This is a STL exception of type std::exception.");}//--------------------------------------------------------------------------------------------------// 抛出未知异常static void RaiseUnknownException(){throw "This is an unknown exception.";}//--------------------------------------------------------------------------------------------------};}
}

整段代码定义了一个异常信息结构体ExceptionInfo和一个异常辅助类ExceptionHelperExceptionInfo用于封装异常来源和消息,而ExceptionHelper提供了获取本地异常信息和抛出不同类型异常的方法。

2.

#include "ManagedPCH.h"// 引入System和System::IO命名空间
using namespace System;
using namespace System::IO;// 定义Macad命名空间下的Interop子命名空间
namespace Macad
{namespace Interop{// 文件操作类public ref class FileOperation sealed{private:// 文件操作私有方法static bool _SHFileOperation(UINT func, FILEOP_FLAGS flags, String^ pathFrom, String^ pathTo){// 将路径转换为指针pin_ptr<const wchar_t> pathFromPtr = PtrToStringChars(String::Concat(pathFrom, "\0\0"));pin_ptr<const wchar_t> pathToPtr = String::IsNullOrEmpty(pathTo) ? nullptr : PtrToStringChars(String::Concat(pathTo, "\0\0"));// 初始化文件操作结构体SHFILEOPSTRUCT shf;memset(&shf, 0, sizeof(shf));shf.hwnd = (HWND)(void*)(System::Diagnostics::Process::GetCurrentProcess()->MainWindowHandle);shf.wFunc = func;shf.fFlags = flags;shf.pFrom = pathFromPtr;shf.pTo = pathToPtr;// 执行文件操作auto res = SHFileOperation(&shf);if (res == 0x4c7) // 用户取消操作return false;if (res != 0)throw gcnew System::ComponentModel::Win32Exception(res); // 抛出Win32异常return true;}//--------------------------------------------------------------------------------------------------public:// 删除文件static bool DeleteFile(String^ path){return _SHFileOperation(FO_DELETE, FOF_ALLOWUNDO | FOF_NOCONFIRMATION, path, nullptr);}//--------------------------------------------------------------------------------------------------public:// 移动文件static bool MoveFile(String^ pathFrom, String^ pathTo){if (File::Exists(pathTo) || Directory::Exists(pathTo))throw gcnew IOException("A file or directory with this name already exists."); // 文件或目录已存在return _SHFileOperation(FO_MOVE, FOF_NOCONFIRMATION, pathFrom, pathTo);}//--------------------------------------------------------------------------------------------------public:// 复制文件static bool CopyFile(String^ pathFrom, String^ pathTo){if (File::Exists(pathTo))throw gcnew IOException("A file or directory with this name already exists."); // 文件或目录已存在return _SHFileOperation(FO_COPY, FOF_NOCONFIRMATION, pathFrom, pathTo);}//--------------------------------------------------------------------------------------------------};}
}

这段代码定义了一个文件操作类FileOperation,其中包含了删除文件、移动文件和复制文件的静态方法。这些方法通过调用Windows的SHFileOperation函数来执行文件操作,并处理了可能的异常情况。

3.

#include "ManagedPCH.h"
#include "AIS_PointEx.h"// 实现RTTI扩展
IMPLEMENT_STANDARD_RTTIEXT(AIS_PointEx, AIS_Point)// AIS_PointEx构造函数
AIS_PointEx::AIS_PointEx(const Handle(Geom_Point)& aComponent): ::AIS_Point(aComponent)
{
}//--------------------------------------------------------------------------------------------------// 设置背景颜色
void AIS_PointEx::SetBackgroundColor(const Quantity_Color& theColor)
{if(myBackgroundDrawer.IsNull())return;myBackgroundDrawer->PointAspect()->SetColor(theColor);SynchronizeAspects();
}//--------------------------------------------------------------------------------------------------// 计算显示
void AIS_PointEx::Compute(const Handle(PrsMgr_PresentationManager)& aPresentationManager,const Handle(Prs3d_Presentation)& aPresentation, const Standard_Integer aMode)
{aPresentation->SetInfiniteState(myInfiniteState);if (aMode == 0 && !myBackgroundDrawer.IsNull()){StdPrs_Point::Add(aPresentation, Component(), myBackgroundDrawer);}AIS_Point::Compute(aPresentationManager, aPresentation, aMode);
}//--------------------------------------------------------------------------------------------------// 启用背景
void AIS_PointEx::EnableBackground(double theTransparency)
{if(!myDrawer->HasOwnPointAspect() || myDrawer->PointAspect()->Aspect()->Type() != Aspect_TOM_USERDEFINED)return;int width, height;myDrawer->PointAspect()->Aspect()->GetTextureSize(width, height);myBackgroundDrawer = new Prs3d_Drawer();Handle(Image_PixMap) myImage = new Image_PixMap();myImage->InitZero(Image_Format_Alpha, width, height, 0, (Standard_Byte)(255 * theTransparency));Handle(Graphic3d_AspectMarker3d) aMarkerAspect = new Graphic3d_AspectMarker3d(myImage);Handle(Prs3d_PointAspect) aPointAspect = new Prs3d_PointAspect(aMarkerAspect);aPointAspect->SetTypeOfMarker(Aspect_TOM_USERDEFINED);myBackgroundDrawer->SetPointAspect(aPointAspect);myBackgroundDrawer->SetZLayer(ZLayer());SetToUpdate();UpdatePresentations();
}

这段代码定义了一个名为AIS_PointEx的类,它是AIS_Point类的扩展,用于表示具有背景颜色的点。该类提供了设置背景颜色、计算显示和启用背景的方法。其中,SetBackgroundColor方法用于设置背景颜色,Compute方法用于计算显示并添加背景,EnableBackground方法用于启用背景并设置透明度。

4.

#include "ManagedPCH.h"
#include "AIS_PointEx.h"#using "Macad.Occt.dll" as_friend// 命名空间定义
namespace Macad
{namespace Occt{namespace Ext{// AIS_PointEx类定义public ref class AIS_PointEx sealed : Macad::Occt::AIS_Point{public:// 实现TransientIMPLEMENT_TRANSIENT(AIS_PointEx, AIS_Point);// AIS_PointEx构造函数AIS_PointEx(Macad::Occt::Geom_Point^ aComponent): Macad::Occt::AIS_Point(InitMode::Uninitialized){NativeInstance = new ::AIS_PointEx(aComponent->NativeInstance);}// 启用背景方法void EnableBackground(double theTransparency){NativeInstance->EnableBackground(theTransparency);}// 设置背景颜色方法void SetBackgroundColor(Macad::Occt::Quantity_Color^ aColor){NativeInstance->SetBackgroundColor(*aColor->NativeInstance);}};};}
}

这段代码定义了一个名为AIS_PointEx的扩展类,它是AIS_Point类的派生类,用于表示具有背景颜色的点。该类提供了构造函数用于创建AIS_PointEx对象,并提供了启用背景和设置背景颜色的方法。

5.

#include "ManagedPCH.h"
#include "AIS_ViewCubeEx.h"// 标准RTTI扩展实现
IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCubeEx, AIS_ViewCube)//--------------------------------------------------------------------------------------------------// 计算方法实现
void AIS_ViewCubeEx::Compute(const opencascade::handle<PrsMgr_PresentationManager>& thePrsMgr,const opencascade::handle<Prs3d_Presentation>& thePrs, const Standard_Integer theMode)
{// 设置无限状态thePrs->SetInfiniteState(true);// 如果不是渲染模式,则直接返回if (theMode != 0){return;}// 计算位置const gp_Pnt aLocation = (mySize * 0.5 + myBoxFacetExtension + myAxesPadding) * gp_XYZ(-1.0, -1.0, -1.0);// 显示盒子侧面{Standard_Integer aNbNodes = 0, aNbTris = 0;for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter){createBoxPartTriangles(Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris,(V3d_TypeOfOrientation)aPartIter);}// 如果存在节点,则添加到图形组中if (aNbNodes > 0){Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles(aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal | Graphic3d_ArrayFlags_VertexTexel);Handle(Graphic3d_ArrayOfSegments) aSegs;// 如果需要绘制边界,则创建段组if (myDrawer->FaceBoundaryDraw()){aSegs = new Graphic3d_ArrayOfSegments(aNbNodes, aNbNodes * 2, Graphic3d_ArrayFlags_None);}aNbNodes = aNbTris = 0;// 遍历所有方向,创建盒子的部分三角形for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter){Standard_Integer aTriNodesFrom = aTris->VertexNumber();const Standard_Integer aTriFrom = aNbTris;createBoxPartTriangles(aTris, aNbNodes, aNbTris, (V3d_TypeOfOrientation)aPartIter);// 如果段组为空,则继续下一个方向if (aSegs.IsNull()){continue;}const Standard_Integer aFirstNode = aSegs->VertexNumber();// 添加段组顶点for (Standard_Integer aVertIter = (aNbTris - aTriFrom) > 2 ? aTriNodesFrom + 2 : aTriNodesFrom + 1;aVertIter <= aTris->VertexNumber(); ++aVertIter){aSegs->AddVertex(aTris->Vertice(aVertIter));}aSegs->AddPolylineEdges(aFirstNode + 1, aSegs->VertexNumber(), true);}// 创建图形组,添加到显示{Handle(Graphic3d_Group) aGroupSides = thePrs->NewGroup();aGroupSides->SetClosed(true); // 应该被强制背面消隐属性所替代aGroupSides->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());aGroupSides->AddPrimitiveArray(aTris);}// 如果段组不为空,则创建图形组,添加到显示if (!aSegs.IsNull()){Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();aGroupSegs->SetGroupPrimitivesAspect(myDrawer->FaceBoundaryAspect()->Aspect());aGroupSegs->AddPrimitiveArray(aSegs);}}}// 显示盒子边缘{Standard_Integer aNbNodes = 0, aNbTris = 0;for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter){createBoxPartTriangles(Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris,(V3d_TypeOfOrientation)aPartIter);}// 如果存在节点,则创建图形组,添加到显示if (aNbNodes > 0){Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles(aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);aNbNodes = aNbTris = 0;// 遍历所有方向,创建盒子的部分三角形for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter){const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation)aPartIter;createBoxPartTriangles(aTris, aNbNodes, aNbTris, anOrient);}// 创建图形组,添加到显示Handle(Graphic3d_Group) aGroupEdges = thePrs->NewGroup();aGroupEdges->SetClosed(true);aGroupEdges->SetGroupPrimitivesAspect(myBoxEdgeAspect->Aspect());aGroupEdges->AddPrimitiveArray(aTris);}}// 显示盒子角点{Standard_Integer aNbNodes = 0, aNbTris = 0;for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter){createBoxPartTriangles(Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris,(V3d_TypeOfOrientation)aPartIter);}// 如果存在节点,则创建图形组,添加到显示if (aNbNodes > 0){Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles(aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);aNbNodes = aNbTris = 0;// 遍历所有方向,创建盒子的部分三角形for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter){const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation)aPartIter;createBoxPartTriangles(aTris, aNbNodes, aNbTris, anOrient);}// 创建图形组,添加到显示Handle(Graphic3d_Group) aGroupCorners = thePrs->NewGroup();aGroupCorners->SetClosed(true);aGroupCorners->SetGroupPrimitivesAspect(myBoxCornerAspect->Aspect());aGroupCorners->AddPrimitiveArray(aTris);}}
}//--------------------------------------------------------------------------------------------------// 使用指定颜色突出显示拥有者
void AIS_ViewCubeEx::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr,const Handle(Prs3d_Drawer)& theStyle,const Handle(SelectMgr_EntityOwner)& theOwner)
{// 如果拥有者为空或立即模式关闭,则直接返回if (theOwner.IsNull() || !thePrsMgr->IsImmediateModeOn()){return;}// 获取层级和立方体拥有者const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN? theStyle->ZLayer(): myDrawer->ZLayer();const AIS_ViewCubeOwner* aCubeOwner = dynamic_cast<AIS_ViewCubeOwner*>(theOwner.get());// 获取突出显示的演示对象Handle(Prs3d_Presentation) aHiPrs = GetHilightPresentation(thePrsMgr);aHiPrs->Clear();aHiPrs->CStructure()->ViewAffinity = thePrsMgr->StructureManager()->ObjectAffinity(Handle(Standard_Transient)(this));aHiPrs->SetTransformPersistence(TransformPersistence());aHiPrs->SetZLayer(aLayer);{Handle(Graphic3d_Group) aGroup = aHiPrs->NewGroup();aGroup->SetGroupPrimitivesAspect(theStyle->ShadingAspect()->Aspect());Standard_Integer aNbNodes = 0, aNbTris = 0;createBoxPartTriangles(Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, aCubeOwner->MainOrientation());if (aNbNodes > 0){Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles(aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexTexel);aNbNodes = aNbTris = 0;createBoxPartTriangles(aTris, aNbNodes, aNbTris, aCubeOwner->MainOrientation());aGroup->AddPrimitiveArray(aTris);}}// 如果立即模式打开,则添加到立即列表中if (thePrsMgr->IsImmediateModeOn()){thePrsMgr->AddToImmediateList(aHiPrs);}
}//--------------------------------------------------------------------------------------------------// 创建盒子的部分三角形
void AIS_ViewCubeEx::createBoxSideTriangles(const opencascade::handle<Graphic3d_ArrayOfTriangles>& theTris,Standard_Integer& theNbNodes, Standard_Integer& theNbTris, V3d_TypeOfOrientation theDirection) const
{// 获取方向和位置const gp_Dir aDir = V3d::GetProjAxis(theDirection);const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension);const gp_Ax2 aPosition(aPos, aDir.Reversed());// 创建转换gp_Ax3 aSystem(aPosition);gp_Trsf aTrsf;aTrsf.SetTransformation(aSystem, gp_Ax3());const Standard_Real aHSize = mySize / 2.0f;const Standard_Real aTexU0 = ((float)theDirection) / 6.0f;const Standard_Real aTexU1 = 1.0f / 6.0f + aTexU0;const Standard_Integer aVertFirst = !theTris.IsNull() ? theTris->VertexNumber() : 0;// 更新节点和三角形数量theNbNodes += 4;theNbTris += 2;// 如果三角形为空,则直接返回if (theTris.IsNull()){return;}// 添加顶点和纹理坐标theTris->AddVertex(gp_Pnt(-aHSize, -aHSize, 0.0).Transformed(aTrsf), gp_Pnt2d(aTexU1, 1.0));theTris->AddVertex(gp_Pnt(-aHSize, aHSize, 0.0).Transformed(aTrsf), gp_Pnt2d(aTexU0, 1.0));theTris->AddVertex(gp_Pnt(aHSize, aHSize, 0.0).Transformed(aTrsf), gp_Pnt2d(aTexU0, 0.0));theTris->AddVertex(gp_Pnt(aHSize, -aHSize, 0.0).Transformed(aTrsf), gp_Pnt2d(aTexU1, 0.0));theTris->AddQuadTriangleEdges(aVertFirst + 1, aVertFirst + 2, aVertFirst + 3, aVertFirst + 4);// 设置法线const gp_Dir aNorm = gp::DZ().Transformed(aTrsf);for (Standard_Integer aVertIter = aVertFirst + 1; aVertIter <= theTris->VertexNumber(); ++aVertIter){theTris->SetVertexNormal(aVertIter, -aNorm);}
}//--------------------------------------------------------------------------------------------------// 设置纹理
void AIS_ViewCubeEx::SetTexture(const opencascade::handle<Image_PixMap>& thePixMap)
{// 创建纹理对象Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D(thePixMap);aTexture->SetAnisoFilter(Graphic3d_LOTA_QUALITY);// 设置着色属性的纹理映射myDrawer->ShadingAspect()->Aspect()->SetTextureMap(aTexture);myDrawer->ShadingAspect()->Aspect()->SetTextureMapOn(true);myDynHilightDrawer->ShadingAspect()->Aspect()->SetTextureMap(aTexture);myDynHilightDrawer->ShadingAspect()->Aspect()->SetTextureMapOn(true);// 同步属性SynchronizeAspects();
}

这段代码实现了一个名为AIS_ViewCubeEx的类,它是AIS_ViewCube的扩展。主要包含了以下功能:

  1. 计算方法:根据指定参数计算视图立方体的外观。
  2. 突出显示方法:突出显示拥有者的部分三角形。
  3. 创建盒子的部分三角形方法:根据方向创建盒子的部分三角形。
  4. 设置纹理方法:为视图立方体设置纹理。

该类的功能主要用于在三维图形场景中显示一个带有纹理的视图立方体,用于表示当前视图方向。

6.

#include "ManagedPCH.h"                           // 包含托管代码的预编译头文件,加快编译速度#include "AIS_ViewCubeEx.h"                       // 包含未托管 AIS_ViewCubeEx 类的头文件#using "Macad.Occt.dll" as_friend                // 导入 Macad.Occt.dll 程序集,并允许其在当前上下文中作为友元程序集使用namespace Macad                                     // 定义 Macad 命名空间
{namespace Occt                                  // 定义 Occt 命名空间,嵌套在 Macad 命名空间中{namespace Ext                               // 定义 Ext 命名空间,嵌套在 Occt 命名空间中{public ref class AIS_ViewCubeEx sealed  // 声明 AIS_ViewCubeEx 类,标记为 sealed 表示不能被继承{public:IMPLEMENT_TRANSIENT(AIS_ViewCubeEx, AIS_ViewCube);  // 实现 AIS_ViewCubeEx 类的瞬态行为AIS_ViewCubeEx()                    // 构造函数,初始化未托管 AIS_ViewCubeEx 类的新实例: Macad::Occt::AIS_ViewCube(InitMode::Uninitialized) // 调用基类构造函数{NativeInstance = new ::AIS_ViewCubeEx();  // 创建未托管 AIS_ViewCubeEx 类的实例}public:void SetTexture(Image_PixMap^ thePixMap)  // 设置视图立方体的纹理{NativeInstance->SetTexture(thePixMap->NativeInstance);  // 调用未托管 AIS_ViewCubeEx 类的方法}};};}
}

这段代码定义了一个托管包装类 AIS_ViewCubeEx,用于对未托管的 AIS_ViewCubeEx 类进行托管访问。

7.

#include "ManagedPCH.h"                           // 包含托管代码的预编译头文件#using "Macad.Occt.dll" as_friend                // 导入 Macad.Occt.dll 程序集,并允许其在当前上下文中作为友元程序集使用using namespace System;                          // 使用 System 命名空间
using namespace System::Collections::Generic;     // 使用 System.Collections.Generic 命名空间namespace Macad                                     // 定义 Macad 命名空间
{namespace Occt                                  // 定义 Occt 命名空间,嵌套在 Macad 命名空间中{namespace Helper                            // 定义 Helper 命名空间,嵌套在 Occt 命名空间中{// 用于 AisHelper::DisableGlobalClipPlanesHandle(::Graphic3d_SequenceOfHClipPlane) EmptySequenceOfClipPlanes = []  // 定义一个空的裁剪平面序列{auto seq = new ::Graphic3d_SequenceOfHClipPlane();               // 创建裁剪平面序列seq->SetOverrideGlobal(true);                                     // 设置覆盖全局裁剪平面return seq;                                                       // 返回裁剪平面序列}();//--------------------------------------------------------------------------------------------------// AisHelper 类,包含一些辅助方法用于与 AIS_InteractiveContext 交互public ref class AisHelper{public:// 从 AIS_InteractiveContext 中获取检测到的形状static Macad::Occt::TopoDS_Shape^ GetDetectedShapeFromContext(Macad::Occt::AIS_InteractiveContext^ aisContext ){auto owner = aisContext->NativeInstance->DetectedOwner();         // 获取检测到的实体所有者if (owner.IsNull())                                              // 如果实体所有者为空return nullptr;                                               // 返回空值auto brepOwner = Handle(::StdSelect_BRepOwner)::DownCast(owner);  // 尝试转换为 BRepOwnerif (brepOwner.IsNull() || !brepOwner->HasShape())                // 如果转换失败或者形状不存在return nullptr;                                               // 返回空值return gcnew Macad::Occt::TopoDS_Shape(new ::TopoDS_Shape(brepOwner->Shape()));  // 返回检测到的形状}//--------------------------------------------------------------------------------------------------// 从 AIS_InteractiveContext 中进行拾取static int PickFromContext(Macad::Occt::AIS_InteractiveContext^ aisContext,List<ValueTuple<int,int>>^ pointList,bool bAllowOverlapDetection,Macad::Occt::V3d_View^ theView,List<Macad::Occt::AIS_InteractiveObject^>^ interactives,List<Macad::Occt::TopoDS_Shape^>^ shapes){::TColgp_Array1OfPnt2d points(1,pointList->Count);               // 创建点数组for(int pointIndex=0; pointIndex < pointList->Count; pointIndex++) // 遍历传入的点列表{auto tuple = pointList[pointIndex];points.SetValue(pointIndex+1, ::gp_Pnt2d(tuple.Item1, tuple.Item2));  // 将点值添加到数组中}auto selector = aisContext->NativeInstance->MainSelector();      // 获取主选择器selector->AllowOverlapDetection(bAllowOverlapDetection);         // 设置是否允许重叠检测selector->Pick(points, theView->NativeInstance);                 // 进行拾取return _PickFromSelector(*selector, interactives, shapes);        // 调用内部方法处理拾取结果}//--------------------------------------------------------------------------------------------------// 从 AIS_InteractiveContext 中进行拾取static int PickFromContext(Macad::Occt::AIS_InteractiveContext^ aisContext,const Standard_Integer theXPMin, const Standard_Integer theYPMin, const Standard_Integer theXPMax,const Standard_Integer  theYPMax,bool bAllowOverlapDetection,Macad::Occt::V3d_View^ theView,List<Macad::Occt::AIS_InteractiveObject^>^ interactives,List<Macad::Occt::TopoDS_Shape^>^ shapes){auto selector = aisContext->NativeInstance->MainSelector();      // 获取主选择器selector->AllowOverlapDetection(bAllowOverlapDetection);         // 设置是否允许重叠检测selector->Pick(theXPMin, theYPMin, theXPMax, theYPMax, theView->NativeInstance);  // 进行拾取return _PickFromSelector(*selector, interactives, shapes);        // 调用内部方法处理拾取结果}//--------------------------------------------------------------------------------------------------private:// 从选择器中获取拾取结果static int _PickFromSelector(::StdSelect_ViewerSelector3d& selector, List<Macad::Occt::AIS_InteractiveObject^>^ interactives,List<Macad::Occt::TopoDS_Shape^>^ shapes){int count = 0;                                                  // 初始化计数器for (Standard_Integer aPickIter = 1; aPickIter <= selector.NbPicked(); ++aPickIter)  // 遍历拾取结果{auto owner = selector.Picked (aPickIter);                   // 获取拾取到的实体所有者if (owner.IsNull() || !owner->HasSelectable())             // 如果实体所有者为空或者不可选择continue;                                               // 继续下一次循环count++;                                                    // 增加计数器if(interactives != nullptr)                                // 如果需要返回交互对象列表{Handle(::AIS_InteractiveObject) interactive = Handle(::AIS_InteractiveObject)::DownCast(owner->Selectable());  // 尝试转换为 AIS_InteractiveObjectif (!interactive.IsNull())                              // 如果转换成功interactives->Add(Macad::Occt::AIS_InteractiveObject::CreateDowncasted(interactive.get()));  // 添加到交互对象列表中}if(shapes != nullptr)                                      // 如果需要返回形状列表{auto brepOwner = Handle(::StdSelect_BRepOwner)::DownCast(owner);  // 尝试转换为 BRepOwnerif (!brepOwner.IsNull() && brepOwner->HasShape())       // 如果转换成功且形状存在shapes->Add(gcnew Macad::Occt::TopoDS_Shape(new ::TopoDS_Shape(brepOwner->Shape())));  // 添加到形状列表中}}return count;                                                   // 返回拾取的实体数量}//--------------------------------------------------------------------------------------------------public:// 设置橡皮筋的点static void SetRubberbandPoints(Macad::Occt::WNT_Window^ wntWindow, Macad::Occt::AIS_RubberBand^ aisRubberband, List<ValueTuple<int,int>>^ pointList){Standard_Integer width, height;                                // 定义宽度和高度变量wntWindow->Size(width, height);                               // 获取窗口大小auto rubberband = aisRubberband->NativeInstance;              // 获取橡皮筋实例rubberband->ClearPoints();                                    // 清除已有的点for each (auto point in pointList)                            // 遍历传入的点列表{::Graphic3d_Vec2i vec2i(point.Item1, height - point.Item2);  // 创建 2D 向量rubberband->AddPoint(vec2i);                              // 添加点到橡皮筋}}//--------------------------------------------------------------------------------------------------// 禁用全局裁剪平面static void DisableGlobalClipPlanes(Macad::Occt::PrsMgr_PresentableObject^ obj){obj->NativeInstance->SetClipPlanes(EmptySequenceOfClipPlanes);  // 将对象的裁剪平面设置为空}//--------------------------------------------------------------------------------------------------};} // namespace Helper} // namespace Occt
} // namespace Macad

这段代码定义了一个托管辅助类 AisHelper,其中包含了一系列用于与 AIS_InteractiveContext 交互的静态方法。

8.

#include "ManagedPCH.h"                           // 包含托管代码的预编译头文件
#include "BRepTools.hxx"                          // 包含 BRep 工具类头文件
#include "BRepTools_ShapeSet.hxx"                 // 包含 BRep ShapeSet 类头文件
#include "BinTools_ShapeSet.hxx"                  // 包含 BinTools ShapeSet 类头文件#using "Macad.Occt.dll" as_friend                // 导入 Macad.Occt.dll 程序集,并允许其在当前上下文中作为友元程序集使用using namespace System;                          // 使用 System 命名空间
using namespace System::Runtime::InteropServices; // 使用 System.Runtime.InteropServices 命名空间namespace Macad                                     // 定义 Macad 命名空间
{namespace Occt                                  // 定义 Occt 命名空间,嵌套在 Macad 命名空间中{namespace Helper                            // 定义 Helper 命名空间,嵌套在 Occt 命名空间中{// BRepExchange 类,包含一些用于读写 BRep 数据的静态方法public ref class BRepExchange{public:// 将形状写入 ASCII 格式的字节数组static array<System::Byte>^ WriteASCII(Macad::Occt::TopoDS_Shape^ shape, bool includeTriangles){std::stringstream out;                                            // 创建输出流::BRepTools_ShapeSet shapeSet;                                    // 创建 BRep ShapeSetshapeSet.SetWithTriangles(includeTriangles);                       // 设置是否包含三角形shapeSet.SetFormatNb(1);                                           // 设置格式编号shapeSet.Add(*shape->NativeInstance);                              // 添加形状到 ShapeSetshapeSet.Write(out);                                               // 将 ShapeSet 写入流shapeSet.Write(*shape->NativeInstance, out);                        // 将形状写入流if (out.str().length() > 0)                                        // 如果流的长度大于 0{int length = (int)out.str().length();                          // 获取流的长度auto byteArray = gcnew array<System::Byte>(length + 1);        // 创建字节数组Marshal::Copy((IntPtr)(char*)(out.str().c_str()), byteArray, 0, length);  // 复制流到字节数组return byteArray;                                              // 返回字节数组}return nullptr;                                                     // 返回空值}// 从 ASCII 格式的字节数组中读取形状static Macad::Occt::TopoDS_Shape^ ReadASCII(array<System::Byte>^ bytes){int length = bytes->Length;                                         // 获取字节数组的长度auto buffer = new char[length];                                     // 创建字符缓冲区Marshal::Copy(bytes, 0, (IntPtr)buffer, length);                     // 将字节数组复制到缓冲区std::istringstream in(std::string(buffer, length));                  // 创建输入流::BRepTools_ShapeSet shapeSet;                                      // 创建 BRep ShapeSetshapeSet.Read(in);                                                    // 从流中读取 ShapeSetif (shapeSet.NbShapes() == 0)                                        // 如果 ShapeSet 中没有形状return nullptr;                                                   // 返回空值::TopoDS_Shape* shape = new ::TopoDS_Shape();                        // 创建形状指针shapeSet.Read(*shape, in);                                            // 从流中读取形状return gcnew Macad::Occt::TopoDS_Shape(shape);                       // 返回形状}// 将形状写入二进制格式的字节数组static array<System::Byte>^ WriteBinary(Macad::Occt::TopoDS_Shape^ shape, bool includeTriangles){std::stringstream out;                                            // 创建输出流::BinTools_ShapeSet shapeSet;                                     // 创建 BinTools ShapeSetshapeSet.SetFormatNb(1);                                          // 设置格式编号shapeSet.SetWithTriangles(includeTriangles);                       // 设置是否包含三角形shapeSet.Add(*shape->NativeInstance);                              // 添加形状到 ShapeSetshapeSet.Write(out);                                               // 将 ShapeSet 写入流shapeSet.Write(*shape->NativeInstance, out);                        // 将形状写入流if (out.str().length() > 0)                                        // 如果流的长度大于 0{int length = (int)out.str().length();                          // 获取流的长度auto byteArray = gcnew array<System::Byte>(length + 1);        // 创建字节数组Marshal::Copy((IntPtr)(char*)(out.str().c_str()), byteArray, 0, length);  // 复制流到字节数组return byteArray;                                              // 返回字节数组}return nullptr;                                                     // 返回空值}// 从二进制格式的字节数组中读取形状static Macad::Occt::TopoDS_Shape^ ReadBinary(array<System::Byte>^ bytes){int length = bytes->Length;                                         // 获取字节数组的长度auto buffer = new char[length];                                     // 创建字符缓冲区Marshal::Copy(bytes, 0, (IntPtr)buffer, length);                     // 将字节数组复制到缓冲区std::istringstream in(std::string(buffer, length));                  // 创建输入流::BinTools_ShapeSet shapeSet;                                       // 创建 BinTools ShapeSetshapeSet.Read(in);                                                   // 从流中读取 ShapeSetif (shapeSet.NbShapes() == 0)                                       // 如果 ShapeSet 中没有形状return nullptr;                                                  // 返回空值::TopoDS_Shape* shape = new ::TopoDS_Shape();                       // 创建形状指针shapeSet.ReadSubs(*shape, in, shapeSet.NbShapes());                  // 从流中读取形状return gcnew Macad::Occt::TopoDS_Shape(shape);                      // 返回形状}};}}
}

这段代码定义了一个托管辅助类 BRepExchange,其中包含了一些用于读写 BRep 数据的静态方法。

9.

#include "ManagedPCH.h"                            // 包含托管代码的预编译头文件
#include "OpenGl_GraphicDriver.hxx"                // 包含 OpenGl 图形驱动类头文件#using "Macad.Occt.dll" as_friend                 // 导入 Macad.Occt.dll 程序集,并允许其在当前上下文中作为友元程序集使用namespace Macad                                      // 定义 Macad 命名空间
{namespace Occt                                   // 定义 Occt 命名空间,嵌套在 Macad 命名空间中{namespace Helper                             // 定义 Helper 命名空间,嵌套在 Occt 命名空间中{// Graphic3d 类,包含创建 OpenGl 图形驱动的静态方法public ref class Graphic3d{public:// 创建 OpenGl 图形驱动实例static Macad::Occt::Graphic3d_GraphicDriver^ CreateOpenGlDriver(){Handle(::Aspect_DisplayConnection) aDisplayConnection;            // 创建显示连接句柄::OpenGl_GraphicDriver* Driver = new ::OpenGl_GraphicDriver(aDisplayConnection);  // 创建 OpenGl 图形驱动指针Driver->ChangeOptions().ffpEnable = false;                       // 禁用固定管线Driver->ChangeOptions().contextDebug = false;                     // 禁用上下文调试return gcnew Macad::Occt::Graphic3d_GraphicDriver(Driver);       // 返回 Graphic3d_GraphicDriver 实例}};}}
}

这段代码定义了一个托管辅助类 Graphic3d,其中包含了一个静态方法 CreateOpenGlDriver,用于创建 OpenGl 图形驱动的实例。

10.

#include "ManagedPCH.h"                            // 包含托管代码的预编译头文件#include <HLRAlgo_Projector.hxx>                  // 包含 HLRAlgo_Projector 类头文件
#include <HLRBRep_Algo.hxx>                       // 包含 HLRBRep_Algo 类头文件
#include <HLRBRep_HLRToShape.hxx>                 // 包含 HLRBRep_HLRToShape 类头文件
#include <HLRBRep_PolyAlgo.hxx>                   // 包含 HLRBRep_PolyAlgo 类头文件
#include <HLRBRep_PolyHLRToShape.hxx>             // 包含 HLRBRep_PolyHLRToShape 类头文件#using "Macad.Occt.dll" as_friend                // 导入 Macad.Occt.dll 程序集,并允许其在当前上下文中作为友元程序集使用using namespace System::Collections::Generic;     // 使用泛型集合命名空间namespace Macad                                     // 定义 Macad 命名空间
{namespace Occt                                  // 定义 Occt 命名空间,嵌套在 Macad 命名空间中{namespace Helper                            // 定义 Helper 命名空间,嵌套在 Occt 命名空间中{// 定义 HlrEdgeTypes 枚举,表示边类型[System::Flags]public enum struct HlrEdgeTypes{None           = 0,                  // 无边类型VisibleSharp   = 1 << 0,             // 可见锐边VisibleSmooth  = 1 << 1,             // 可见平滑边VisibleSewn    = 1 << 2,             // 可见缝合边VisibleOutline = 1 << 3,             // 可见轮廓边HiddenSharp    = 1 << 4,             // 隐藏锐边HiddenSmooth   = 1 << 5,             // 隐藏平滑边HiddenSewn     = 1 << 6,             // 隐藏缝合边HiddenOutline  = 1 << 7              // 隐藏轮廓边};//--------------------------------------------------------------------------------------------------// HlrBRepAlgoBase 抽象类,表示 HLR 边缘算法基类public ref class HlrBRepAlgoBase abstract{protected:HLRAlgo_Projector* _Projector;      // HLR 投影器指针//--------------------------------------------------------------------------------------------------// 默认构造函数,初始化 HLR 投影器HlrBRepAlgoBase(){_Projector = new HLRAlgo_Projector();  // 创建 HLR 投影器实例}//--------------------------------------------------------------------------------------------------// 析构函数,释放资源~HlrBRepAlgoBase(){this->!HlrBRepAlgoBase();}//--------------------------------------------------------------------------------------------------// 终结器,释放资源!HlrBRepAlgoBase(){if (_Projector != nullptr){delete _Projector;_Projector = nullptr;}}//--------------------------------------------------------------------------------------------------public:// 设置投影变换为给定坐标系void SetProjection(Ax3 CS){STRUCT_PIN(CS, Ax3, gp_Ax3);                    // 将托管结构体转换为针对非托管代码的指针delete _Projector;                              // 删除旧的 HLR 投影器::gp_Trsf trsf;                                 // 创建几何变换对象trsf.SetTransformation(*CS_ptr);                // 设置几何变换_Projector = new ::HLRAlgo_Projector(trsf, false, 0); // 创建新的 HLR 投影器}//--------------------------------------------------------------------------------------------------// 设置投影变换为给定变换void SetProjection(Trsf Transform){STRUCT_PIN(Transform, Trsf, gp_Trsf);           // 将托管结构体转换为针对非托管代码的指针delete _Projector;                              // 删除旧的 HLR 投影器_Projector = new HLRAlgo_Projector(*Transform_ptr, false, 0); // 创建新的 HLR 投影器}//--------------------------------------------------------------------------------------------------// 获取结果形状Macad::Occt::TopoDS_Shape^ GetResult(HlrEdgeTypes type){return GetResult(type, nullptr);}// 获取结果形状的虚拟方法,需要在派生类中实现virtual Macad::Occt::TopoDS_Shape^ GetResult(HlrEdgeTypes type, Macad::Occt::TopoDS_Shape^ sourceShape) abstract;// 更新操作的虚拟方法,需要在派生类中实现virtual void Update() abstract;};//--------------------------------------------------------------------------------------------------// HlrBRepAlgo 类,表示 HLR 边缘算法public ref class HlrBRepAlgo : HlrBRepAlgoBase{private:Handle(::HLRBRep_Algo)* _Algo;             // HLR 边缘算法句柄::HLRBRep_HLRToShape* _Extractor;          // HLR 提取器指针//--------------------------------------------------------------------------------------------------public:// 构造函数,初始化 HLR 边缘算法HlrBRepAlgo(IEnumerable<Macad::Occt::TopoDS_Shape^>^ shapes): HlrBRepAlgoBase()                     // 调用基类构造函数{_Algo = new Handle(::HLRBRep_Algo)(new ::HLRBRep_Algo()); // 创建 HLR 边缘算法句柄_Extractor = new HLRBRep_HLRToShape(*_Algo);             // 创建 HLR 提取器for each (Macad::Occt::TopoDS_Shape^ shape in shapes){(*_Algo)->Add(*shape->NativeInstance);             // 将形状添加到 HLR 边缘算法中}}//--------------------------------------------------------------------------------------------------// 析构函数,释放资源~HlrBRepAlgo(){this->!HlrBRepAlgo();}//--------------------------------------------------------------------------------------------------// 终结器,释放资源!HlrBRepAlgo(){if (_Extractor != nullptr){delete _Extractor;                // 删除 HLR 提取器}_Extractor = nullptr;if (_Algo != nullptr){delete _Algo;                    // 删除 HLR 边缘算法句柄}_Algo = nullptr;}//--------------------------------------------------------------------------------------------------// 更新 HLR 边缘算法void Update() override{(*_Algo)->Projector(*_Projector);         // 设置投影器(*_Algo)->Update();                        // 更新 HLR 边缘算法(*_Algo)->Hide();                          // 隐藏结果}//--------------------------------------------------------------------------------------------------// 获取结果形状Macad::Occt::TopoDS_Shape^ GetResult(HlrEdgeTypes type, Macad::Occt::TopoDS_Shape^ sourceShape) override{bool all = sourceShape == nullptr;           // 判断是否应用于全部形状::TopoDS_Shape* src = all ? nullptr : sourceShape->NativeInstance; // 获取源形状指针// 提取结果形状::TopoDS_Shape shape;shape.Nullify();switch (type){case HlrEdgeTypes::VisibleSharp:shape = all ? _Extractor->VCompound() : _Extractor->VCompound(*src);break;case HlrEdgeTypes::VisibleSmooth:shape = all ? _Extractor->Rg1LineVCompound() : _Extractor->Rg1LineVCompound(*src);break;case HlrEdgeTypes::VisibleSewn:shape = all ? _Extractor->RgNLineVCompound() : _Extractor->RgNLineVCompound(*src);break;case HlrEdgeTypes::VisibleOutline:shape = all ? _Extractor->OutLineVCompound() : _Extractor->OutLineVCompound(*src);break;case HlrEdgeTypes::HiddenSharp:shape = all ? _Extractor->HCompound() : _Extractor->HCompound(*src);break;case HlrEdgeTypes::HiddenSmooth:shape = all ? _Extractor->Rg1LineHCompound() : _Extractor->Rg1LineHCompound(*src);break;case HlrEdgeTypes::HiddenSewn:shape = all ? _Extractor->RgNLineHCompound() : _Extractor->RgNLineHCompound(*src);break;case HlrEdgeTypes::HiddenOutline:shape = all ? _Extractor->OutLineHCompound() : _Extractor->OutLineHCompound(*src);break;}if (shape.IsNull())return nullptr;return gcnew Macad::Occt::TopoDS_Shape(new ::TopoDS_Shape(shape));}};//--------------------------------------------------------------------------------------------------// HlrBRepAlgoPoly 类,表示 HLR 边缘算法多边形版public ref class HlrBRepAlgoPoly : public HlrBRepAlgoBase{private:Handle(::HLRBRep_PolyAlgo)* _Algo;         // HLR 边缘算法多边形版句柄::HLRBRep_PolyHLRToShape* _Extractor;      // HLR 提取器指针//--------------------------------------------------------------------------------------------------public:// 构造函数,初始化 HLR 边缘算法多边形版HlrBRepAlgoPoly(IEnumerable<Macad::Occt::TopoDS_Shape^>^ shapes): HlrBRepAlgoBase()                    // 调用基类构造函数, _Extractor(nullptr){_Algo = new Handle(::HLRBRep_PolyAlgo)(new ::HLRBRep_PolyAlgo()); // 创建 HLR 边缘算法多边形版句柄_Extractor = new ::HLRBRep_PolyHLRToShape();                      // 创建 HLR 提取器for each (Macad::Occt::TopoDS_Shape^ shape in shapes){// 确保所有形状都有网格if (::BRepTools::Triangulation(*shape->NativeInstance, Precision::Infinite()) == Standard_False){::BRepMesh_IncrementalMesh aMesher(*shape->NativeInstance, 0.1); // 生成三角网格}(*_Algo)->Load(*shape->NativeInstance);                          // 将形状加载到 HLR 边缘算法多边形版中}}//--------------------------------------------------------------------------------------------------// 析构函数,释放资源~HlrBRepAlgoPoly(){this->!HlrBRepAlgoPoly();}//--------------------------------------------------------------------------------------------------// 终结器,释放资源!HlrBRepAlgoPoly(){if (_Extractor != nullptr){delete _Extractor;               // 删除 HLR 提取器}_Extractor = nullptr;if (_Algo != nullptr){delete _Algo;                   // 删除 HLR 边缘算法多边形版句柄}_Algo = nullptr;}//--------------------------------------------------------------------------------------------------// 更新 HLR 边缘算法多边形版void Update() override{// 执行更新操作(*_Algo)->Projector(*_Projector);         // 设置投影器(*_Algo)->Update();                        // 更新 HLR 边缘算法多边形版_Extractor->Update(*_Algo);                // 更新 HLR 提取器}//--------------------------------------------------------------------------------------------------// 获取结果形状Macad::Occt::TopoDS_Shape^ GetResult(HlrEdgeTypes type, Macad::Occt::TopoDS_Shape^ sourceShape) override{bool all = sourceShape == nullptr;           // 判断是否应用于全部形状::TopoDS_Shape* src = all ? nullptr : sourceShape->NativeInstance; // 获取源形状指针// 提取结果形状::TopoDS_Shape shape;shape.Nullify();switch (type){case HlrEdgeTypes::VisibleSharp:shape = all ? _Extractor->VCompound() : _Extractor->VCompound(*src);break;case HlrEdgeTypes::VisibleSmooth:shape = all ? _Extractor->Rg1LineVCompound() : _Extractor->Rg1LineVCompound(*src);break;case HlrEdgeTypes::VisibleSewn:shape = all ? _Extractor->RgNLineVCompound() : _Extractor->RgNLineVCompound(*src);break;case HlrEdgeTypes::VisibleOutline:shape = all ? _Extractor->OutLineVCompound() : _Extractor->OutLineVCompound(*src);break;case HlrEdgeTypes::HiddenSharp:shape = all ? _Extractor->HCompound() : _Extractor->HCompound(*src);break;case HlrEdgeTypes::HiddenSmooth:shape = all ? _Extractor->Rg1LineHCompound() : _Extractor->Rg1LineHCompound(*src);break;case HlrEdgeTypes::HiddenSewn:shape = all ? _Extractor->RgNLineHCompound() : _Extractor->RgNLineHCompound(*src);break;case HlrEdgeTypes::HiddenOutline:shape = all ? _Extractor->OutLineHCompound() : _Extractor->OutLineHCompound(*src);break;}if (shape.IsNull())return nullptr;return gcnew Macad::Occt::TopoDS_Shape(new ::TopoDS_Shape(shape));}};}}
}

这段C++/CLI代码定义了与OpenCascade框架中的HLR(隐藏线消除)算法相关的几个类和枚举。HlrEdgeTypes枚举指定了不同类型的边,而HlrBRepAlgoBase、HlrBRepAlgo和HlrBRepAlgoPoly这几个类则提供了在BRep(边界表示)形状上执行HLR操作的功能,这些操作使用了不同的算法和选项。

11.

#include "ManagedPCH.h" // 包含预编译头文件#include <Interface_Static.hxx> // 包含接口静态类的头文件
#include <IGESControl_Writer.hxx> // 包含 IGES 写入器的头文件
#include <IGESControl_Controller.hxx> // 包含 IGES 控制器的头文件
#include <IGESControl_Reader.hxx> // 包含 IGES 读取器的头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间
using namespace System::Runtime::InteropServices; // 使用 InteropServices 命名空间namespace Macad // Macad 命名空间开始
{
namespace Occt // Occt 命名空间开始
{
namespace Helper // Helper 命名空间开始
{// 定义 IgesWriter 类public ref class IgesWriter{IGESControl_Writer* _Writer; // IGES 写入器指针//--------------------------------------------------------------------------------------------------public:// 构造函数IgesWriter(){IGESControl_Controller::Init(); // 初始化 IGES 控制器_Writer = new IGESControl_Writer("MM", 1); // 创建 IGES 写入器对象,设置单位为毫米}//--------------------------------------------------------------------------------------------------// 析构函数virtual ~IgesWriter(){this->!IgesWriter();}//--------------------------------------------------------------------------------------------------// 显式析构函数!IgesWriter(){if(_Writer != nullptr){delete _Writer; // 释放 IGES 写入器对象的内存_Writer = nullptr;}}//--------------------------------------------------------------------------------------------------// 向 IGES 写入器中添加形状bool AddShape(Macad::Occt::TopoDS_Shape^ shape){return _Writer->AddShape(*shape->NativeInstance);}//--------------------------------------------------------------------------------------------------// 将 IGES 写入器中的内容写入到文件bool WriteToFile(String^ path){char* pathCString = static_cast<char*>(Marshal::StringToCoTaskMemUTF8(path).ToPointer()); // 将 String 转换为 char*bool result = _Writer->Write(pathCString); // 写入到文件Marshal::FreeCoTaskMem((IntPtr)pathCString); // 释放内存return result;}};//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 定义 IgesReader 类public ref class IgesReader{IGESControl_Reader* _Reader; // IGES 读取器指针//--------------------------------------------------------------------------------------------------public:// 构造函数IgesReader(){IGESControl_Controller::Init(); // 初始化 IGES 控制器Interface_Static::SetIVal("read.iges.bspline.continuity", 2); // 设置 B 样条曲线的连续性处理方式_Reader = new IGESControl_Reader(); // 创建 IGES 读取器对象}//--------------------------------------------------------------------------------------------------// 析构函数virtual ~IgesReader(){this->!IgesReader();}//--------------------------------------------------------------------------------------------------// 显式析构函数!IgesReader(){if(_Reader != nullptr){delete _Reader; // 释放 IGES 读取器对象的内存_Reader = nullptr;}}//--------------------------------------------------------------------------------------------------// 从 IGES 文件中获取根形状Macad::Occt::TopoDS_Shape^ GetRootShape(){if(_Reader->TransferRoots() == 0)return nullptr;return gcnew TopoDS_Shape(new ::TopoDS_Shape(_Reader->OneShape()));}//--------------------------------------------------------------------------------------------------// 从文件中读取形状bool ReadFromFile(String^ path){char* pathCString = static_cast<char*>(Marshal::StringToCoTaskMemUTF8(path).ToPointer()); // 将 String 转换为 char*bool result = _Reader->ReadFile(pathCString) == IFSelect_RetDone; // 读取文件Marshal::FreeCoTaskMem((IntPtr)pathCString); // 释放内存return result;}};
}
}
}

这段代码定义了两个类:IgesWriterIgesReader,分别用于将 OpenCascade 中的形状写入到 IGES 文件中,以及从 IGES 文件中读取形状。这两个类提供了操作 IGES 文件的接口,并通过使用 OpenCascade 中的 IGES 控制器和读写器来实现。

12.

#include "ManagedPCH.h" // 包含预编译头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{#pragma unmanaged // 定义未管理代码块// 定义 NativeMessageRouter 类,继承自 ::Message_Printerpublic class NativeMessageRouter : public ::Message_Printer{DEFINE_STANDARD_RTTIEXT(NativeMessageRouter, ::Message_Printer) // 定义 RTTIpublic:// 定义消息回调函数指针类型typedef void (__stdcall *MessageCallbackFunc) (const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity);// 构造函数,接受消息回调函数指针作为参数NativeMessageRouter(MessageCallbackFunc messageCallback){_MessageCallback = messageCallback; // 设置消息回调函数}//--------------------------------------------------------------------------------------------------// 析构函数~NativeMessageRouter(){_MessageCallback = nullptr; // 清空消息回调函数指针}//--------------------------------------------------------------------------------------------------protected:// 重写 send 函数,将消息发送给消息回调函数void send (const ::TCollection_AsciiString& theString, const ::Message_Gravity theGravity) const override{if(_MessageCallback != nullptr){_MessageCallback(theString, theGravity); // 调用消息回调函数}}//--------------------------------------------------------------------------------------------------private:MessageCallbackFunc _MessageCallback; // 消息回调函数指针}; // class NativeMessageRouterIMPLEMENT_STANDARD_RTTIEXT(NativeMessageRouter, ::Message_Printer) // 实现 RTTI//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------#pragma managed // 定义托管代码块// 定义 MessageRouter 类,继承自 Standard_Transientpublic ref class MessageRouter : Standard_Transient{public:// 声明消息事件委托delegate void MessageEvent(String^ text, Message_Gravity gravity);// 声明消息到达事件MessageEvent^ MessageArrived;//--------------------------------------------------------------------------------------------------// 构造函数MessageRouter(): Standard_Transient(InitMode::Uninitialized) // 调用父类构造函数{// 创建消息回调委托_NativeCallbackDelegate = gcnew NativeCallbackDelegate(this, &MessageRouter::_NativeCallback);// 将委托转换为函数指针Runtime::InteropServices::GCHandle gch = Runtime::InteropServices::GCHandle::Alloc(_NativeCallbackDelegate);IntPtr ip = Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(_NativeCallbackDelegate);NativeMessageRouter::MessageCallbackFunc cb = static_cast<NativeMessageRouter::MessageCallbackFunc>(ip.ToPointer());// 创建 NativeMessageRouter 实例并注册为消息打印器Handle(NativeMessageRouter) messageRouter = new NativeMessageRouter(cb);NativeInstance = (::Standard_Transient*)messageRouter.get();::Message::DefaultMessenger()->AddPrinter(messageRouter);gch.Free(); // 释放委托句柄}//--------------------------------------------------------------------------------------------------// 析构函数~MessageRouter(){this->!MessageRouter();}//--------------------------------------------------------------------------------------------------// 显式析构函数!MessageRouter(){auto messenger = ::Message::DefaultMessenger();if(!messenger.IsNull()){messenger->RemovePrinter((NativeMessageRouter*)NativeInstance); // 移除消息打印器}_NativeCallbackDelegate = nullptr; // 清空委托}//--------------------------------------------------------------------------------------------------// 获取或设置消息的追踪级别property Message_Gravity TraceLevel{Message_Gravity get(){return (Message_Gravity)((NativeMessageRouter*)NativeInstance)->GetTraceLevel(); // 获取追踪级别}void set(Message_Gravity gravity){((NativeMessageRouter*)NativeInstance)->SetTraceLevel((::Message_Gravity)gravity); // 设置追踪级别}}//--------------------------------------------------------------------------------------------------private:// 定义原生回调委托delegate void NativeCallbackDelegate(const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity);NativeCallbackDelegate^ _NativeCallbackDelegate; // 原生回调委托对象// 原生回调函数,将原生消息转换为托管消息并触发事件void _NativeCallback(const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity) {if(MessageArrived != nullptr){const Standard_ExtString extString = theString.ToExtString();MessageArrived(gcnew System::String((const wchar_t *)extString), (Message_Gravity)theGravity); // 触发事件}}}; // class MessageRouter} // namespace Helper} //namespace OCCT
}

这段代码定义了两个类:NativeMessageRouterMessageRouter,用于处理消息传递。NativeMessageRouter 是一个未托管的类,继承自 ::Message_Printer,用于将消息发送到原生代码中的消息回调函数。MessageRouter 是一个托管类,继承自 Standard_Transient,用于处理消息的传递和事件触发。

13

#include "ManagedPCH.h" // 包含预编译头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{#pragma unmanaged // 定义未管理代码块// 定义 NativeMessageRouter 类,继承自 ::Message_Printerpublic class NativeMessageRouter : public ::Message_Printer{DEFINE_STANDARD_RTTIEXT(NativeMessageRouter, ::Message_Printer) // 定义 RTTIpublic:// 定义消息回调函数指针类型typedef void (__stdcall *MessageCallbackFunc) (const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity);// 构造函数,接受消息回调函数指针作为参数NativeMessageRouter(MessageCallbackFunc messageCallback){_MessageCallback = messageCallback; // 设置消息回调函数}//--------------------------------------------------------------------------------------------------// 析构函数~NativeMessageRouter(){_MessageCallback = nullptr; // 清空消息回调函数指针}//--------------------------------------------------------------------------------------------------protected:// 重写 send 函数,将消息发送给消息回调函数void send (const ::TCollection_AsciiString& theString, const ::Message_Gravity theGravity) const override{if(_MessageCallback != nullptr){_MessageCallback(theString, theGravity); // 调用消息回调函数}}//--------------------------------------------------------------------------------------------------private:MessageCallbackFunc _MessageCallback; // 消息回调函数指针}; // class NativeMessageRouterIMPLEMENT_STANDARD_RTTIEXT(NativeMessageRouter, ::Message_Printer) // 实现 RTTI//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------#pragma managed // 定义托管代码块// 定义 MessageRouter 类,继承自 Standard_Transientpublic ref class MessageRouter : Standard_Transient{public:// 声明消息事件委托delegate void MessageEvent(String^ text, Message_Gravity gravity);// 声明消息到达事件MessageEvent^ MessageArrived;//--------------------------------------------------------------------------------------------------// 构造函数MessageRouter(): Standard_Transient(InitMode::Uninitialized) // 调用父类构造函数{// 创建消息回调委托_NativeCallbackDelegate = gcnew NativeCallbackDelegate(this, &MessageRouter::_NativeCallback);// 将委托转换为函数指针Runtime::InteropServices::GCHandle gch = Runtime::InteropServices::GCHandle::Alloc(_NativeCallbackDelegate);IntPtr ip = Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(_NativeCallbackDelegate);NativeMessageRouter::MessageCallbackFunc cb = static_cast<NativeMessageRouter::MessageCallbackFunc>(ip.ToPointer());// 创建 NativeMessageRouter 实例并注册为消息打印器Handle(NativeMessageRouter) messageRouter = new NativeMessageRouter(cb);NativeInstance = (::Standard_Transient*)messageRouter.get();::Message::DefaultMessenger()->AddPrinter(messageRouter);gch.Free(); // 释放委托句柄}//--------------------------------------------------------------------------------------------------// 析构函数~MessageRouter(){this->!MessageRouter();}//--------------------------------------------------------------------------------------------------// 显式析构函数!MessageRouter(){auto messenger = ::Message::DefaultMessenger();if(!messenger.IsNull()){messenger->RemovePrinter((NativeMessageRouter*)NativeInstance); // 移除消息打印器}_NativeCallbackDelegate = nullptr; // 清空委托}//--------------------------------------------------------------------------------------------------// 获取或设置消息的追踪级别property Message_Gravity TraceLevel{Message_Gravity get(){return (Message_Gravity)((NativeMessageRouter*)NativeInstance)->GetTraceLevel(); // 获取追踪级别}void set(Message_Gravity gravity){((NativeMessageRouter*)NativeInstance)->SetTraceLevel((::Message_Gravity)gravity); // 设置追踪级别}}//--------------------------------------------------------------------------------------------------private:// 定义原生回调委托delegate void NativeCallbackDelegate(const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity);NativeCallbackDelegate^ _NativeCallbackDelegate; // 原生回调委托对象// 原生回调函数,将原生消息转换为托管消息并触发事件void _NativeCallback(const ::TCollection_ExtendedString& theString, const ::Message_Gravity theGravity) {if(MessageArrived != nullptr){const Standard_ExtString extString = theString.ToExtString();MessageArrived(gcnew System::String((const wchar_t *)extString), (Message_Gravity)theGravity); // 触发事件}}}; // class MessageRouter} // namespace Helper} //namespace OCCT
}

这段代码定义了两个类:NativeMessageRouterMessageRouter,用于处理消息传递。NativeMessageRouter 是一个未托管的类,继承自 ::Message_Printer,用于将消息发送到原生代码中的消息回调函数。MessageRouter 是一个托管类,继承自 Standard_Transient,用于处理消息的传递和事件触发。

14

#include "ManagedPCH.h" // 包含预编译头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间
using namespace System::Drawing; // 使用 System.Drawing 命名空间
using namespace System::Drawing::Imaging; // 使用 System.Drawing.Imaging 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{// 定义 PixMapHelper 类,用于处理图像数据和位图之间的转换public ref class PixMapHelper{public:// 将 Image_PixMap 转换为 Bitmapstatic Bitmap^ ConvertToBitmap(Macad::Occt::Image_PixMap^ pixMap){// 检查输入是否为空if(pixMap == nullptr)return nullptr;// 获取 Image_PixMap 的原生实例auto pm = pixMap->NativeInstance;PixelFormat pfm;int ciR, ciG, ciB, ciA;// 根据格式设置像素格式和通道顺序switch(pm->Format()){case Image_Format_RGB:ciR = 0; ciG = 1; ciB = 2; ciA = 0;pfm = PixelFormat::Format24bppRgb;break;case Image_Format_BGR:ciR = 2; ciG = 1; ciB = 0; ciA = 0;pfm = PixelFormat::Format24bppRgb;break;case Image_Format_RGB32:ciR = 0; ciG = 1; ciB = 2; ciA = 3;pfm = PixelFormat::Format24bppRgb;break;case Image_Format_RGBA:ciR = 0; ciG = 1; ciB = 2; ciA = 3;pfm = PixelFormat::Format32bppArgb;break;case Image_Format_BGRA:ciR = 2; ciG = 1; ciB = 0; ciA = 3;pfm = PixelFormat::Format32bppArgb;break;default: return nullptr;}// 获取图像宽度和高度int width = (int)pm->Width();int height = (int)pm->Height();// 创建 Bitmap 对象auto bitmap = gcnew Bitmap(width, height, pfm);auto bitmapData = bitmap->LockBits(Drawing::Rectangle(0, 0, width, height), ImageLockMode::ReadOnly, pfm);auto target = (char*)bitmapData->Scan0.ToPointer();if (bitmapData->Stride < 0) {target += bitmapData->Stride * (1 - bitmap->Height);}auto source = pm->Data();for(int iy=0; iy<height; iy++){char* row = target + iy * bitmapData->Stride;for(int ix=0; ix<width; ix++){row[0] = source[ciB];row[1] = source[ciG];row[2] = source[ciR];if(pfm == PixelFormat::Format32bppArgb){row[3] = source[ciA];row += 4;} else {row += 3;}source += pm->SizePixelBytes();}source += pm->RowExtraBytes();}bitmap->UnlockBits(bitmapData);return bitmap;}//--------------------------------------------------------------------------------------------------// 将 Bitmap 转换为 Image_PixMapstatic Macad::Occt::Image_PixMap^ ConvertFromBitmap(Bitmap^ bitmap){// 检查输入是否为空if(bitmap == nullptr)return nullptr;// 设置默认的图像格式和像素大小::Image_Format fmt(::Image_Format_RGB);int pixelSize(3);// 根据 Bitmap 的像素格式设置图像格式和像素大小switch (bitmap->PixelFormat){case PixelFormat::Format24bppRgb: fmt = ::Image_Format_BGR;pixelSize = 3;break;case PixelFormat::Format32bppRgb: fmt = ::Image_Format_BGR32;pixelSize = 4;break;case PixelFormat::Format32bppArgb: fmt = ::Image_Format_BGRA;pixelSize = 4;break;case PixelFormat::Format32bppPArgb: fmt = ::Image_Format_BGRA;pixelSize = 4;break;default: return nullptr;}// 获取图像宽度和高度const int width = (int)bitmap->Width;const int height = (int)bitmap->Height;// 创建 Image_PixMap 对象auto pm = new ::Image_PixMap();if(!pm->InitTrash(fmt, width, height ))return nullptr;pm->SetTopDown(false);auto bitmapData = bitmap->LockBits(Drawing::Rectangle(0, 0, width, height), ImageLockMode::ReadOnly, bitmap->PixelFormat);unsigned char* source = (unsigned char*)bitmapData->Scan0.ToPointer();// 将图像数据复制到 Image_PixMapconst int stride = bitmapData->Stride * -1;if (stride < 0) {source += stride * (1 - bitmap->Height);}unsigned char* target = pm->ChangeData();for(int iy=0; iy<height; iy++){unsigned char* row = source + iy * stride;for(int ix=0; ix<width; ix++){target[0] = row[0];target[1] = row[1];target[2] = row[2];if(pixelSize == 4){target[3] = row[3];}row += pixelSize;target += pm->SizePixelBytes();}target += pm->RowExtraBytes();}bitmap->UnlockBits(bitmapData);return gcnew Macad::Occt::Image_PixMap(pm);}//--------------------------------------------------------------------------------------------------// 从字节数组创建 Image_PixMapstatic Macad::Occt::Image_PixMap^ CreateFromBytes(array<byte>^ byteArray, int height, int width, int pixelSize){// 检查输入是否为空或无效if(byteArray == nullptr || byteArray->Length == 0)return nullptr;// 设置默认的图像格式::Image_Format fmt(pixelSize==4 ? ::Image_Format_BGRA : ::Image_Format_BGR);// 创建 Image_PixMap 对象auto pm = new ::Image_PixMap();if(!pm->InitTrash(fmt, width, height ))return nullptr;pm->SetTopDown(false);// 将字节数组指针固定pin_ptr<byte> sourcePinPtr = &byteArray[0];unsigned char* source = reinterpret_cast<unsigned char*>(sourcePinPtr);// 将字节数组数据复制到 Image_PixMapint stride = width * pixelSize * -1;source += stride * (1 - height);auto target = pm->ChangeData();for(int iy=0; iy<height; iy++){unsigned char* row = source + iy * stride;for(int ix=0; ix<width; ix++){if(pixelSize == 4){if(row[3] > 0){float alpha = (float)row[3] / 255.0f;target[0] = (unsigned char)(row[0] / alpha);target[1] = (unsigned char)(row[1] / alpha);target[2] = (unsigned char)(row[2] / alpha);}else{target[0] = row[0];target[1] = row[1];target[2] = row[2];}target[3] = row[3];} else {target[0] = row[0];target[1] = row[1];target[2] = row[2];}row += pixelSize;target += pm->SizePixelBytes();}target += pm->RowExtraBytes();}return gcnew Macad::Occt::Image_PixMap(pm);}//--------------------------------------------------------------------------------------------------};}}
}

这段代码定义了一个 PixMapHelper 类,用于在 Image_PixMap 类型和 Bitmap 类型之间进行转换。其中包含了三个静态方法:

  1. ConvertToBitmap:将 Image_PixMap 转换为 Bitmap
  2. ConvertFromBitmap:将 Bitmap 转换为 Image_PixMap
  3. CreateFromBytes:从字节数组创建 Image_PixMap

这些方法允许在不同的图像表示之间方便地进行转换,以满足不同场景下的需求。

15

#include "ManagedPCH.h" // 包含预编译头文件#include <STEPControl_StepModelType.hxx> // 包含 STEPControl_StepModelType 头文件
#include <STEPControl_Writer.hxx> // 包含 STEPControl_Writer 头文件
#include <STEPControl_Reader.hxx> // 包含 STEPControl_Reader 头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间
using namespace System::Runtime::InteropServices; // 使用 System.Runtime.InteropServices 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{// 定义 StepWriter 类,用于将形状写入 STEP 文件public ref class StepWriter{STEPControl_Writer* _Writer; // STEPControl_Writer 指针成员//--------------------------------------------------------------------------------------------------public:// 构造函数,初始化 STEPControl_WriterStepWriter(){_Writer = new STEPControl_Writer();}//--------------------------------------------------------------------------------------------------virtual ~StepWriter() // 析构函数{this->!StepWriter();}//--------------------------------------------------------------------------------------------------!StepWriter() // 终结器{if(_Writer != nullptr){delete _Writer;_Writer = nullptr;}}//--------------------------------------------------------------------------------------------------// 将实体添加到 STEP 文件中bool AddSolid(Macad::Occt::TopoDS_Shape^ shape){return _Writer->Transfer(*shape->NativeInstance, STEPControl_AsIs) == IFSelect_RetDone;}//--------------------------------------------------------------------------------------------------// 将 STEP 文件写入到指定路径bool WriteToFile(String^ path){char* pathCString = static_cast<char*>(Marshal::StringToCoTaskMemUTF8(path).ToPointer());bool result = _Writer->Write(pathCString);Marshal::FreeCoTaskMem((IntPtr)pathCString);return result;}};//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 定义 StepReader 类,用于从 STEP 文件读取形状public ref class StepReader{STEPControl_Reader* _Reader; // STEPControl_Reader 指针成员//--------------------------------------------------------------------------------------------------public:// 构造函数,初始化 STEPControl_ReaderStepReader(){_Reader = new STEPControl_Reader();}//--------------------------------------------------------------------------------------------------virtual ~StepReader() // 析构函数{this->!StepReader();}//--------------------------------------------------------------------------------------------------!StepReader() // 终结器{if(_Reader != nullptr){delete _Reader;_Reader = nullptr;}}//--------------------------------------------------------------------------------------------------// 获取 STEP 文件中的根形状Macad::Occt::TopoDS_Shape^ GetRootShape(){if(_Reader->TransferRoots()==0)return nullptr;return gcnew TopoDS_Shape(new ::TopoDS_Shape(_Reader->OneShape()));}//--------------------------------------------------------------------------------------------------// 从文件读取 STEP 文件bool ReadFromFile(String^ path){char* pathCString = static_cast<char*>(Marshal::StringToCoTaskMemUTF8(path).ToPointer());bool result = _Reader->ReadFile(pathCString) == IFSelect_RetDone;Marshal::FreeCoTaskMem((IntPtr)pathCString);return result;}};}}
}

这段代码定义了两个类 StepWriterStepReader,分别用于将形状写入 STEP 文件和从 STEP 文件中读取形状。其中包含了以下功能:

  • StepWriter 类用于将形状写入 STEP 文件,提供了方法 AddSolid 用于添加实体到 STEP 文件,以及方法 WriteToFile 用于将 STEP 文件写入到指定路径。
  • StepReader 类用于从 STEP 文件中读取形状,提供了方法 GetRootShape 用于获取 STEP 文件中的根形状,以及方法 ReadFromFile 用于从文件读取 STEP 文件。

16

#include "ManagedPCH.h" // 包含预编译头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间// 宏定义,用于比较两种形状类型
#define SAMETYPE(x,y) ((x) == (y))
#define AVOID(x,y) (((x) == TopAbs_SHAPE) ? Standard_False : (x) == (y))
#define LESSCOMPLEX(x,y) ((x) > (y))namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{// 定义 TopoDS_Explorer 类,用于遍历拓扑形状public ref class TopoDS_Explorer : Collections::Generic::IEnumerable<TopoDS_Shape^>{private:TopoDS_Shape^ _Shape; // 拓扑形状TopAbs_ShapeEnum _ToFind; // 要查找的形状类型TopAbs_ShapeEnum _ToAvoid; // 要避免的形状类型bool _CumOrientation; // 是否累积方向bool _CumLocation; // 是否累积位置public:// 构造函数TopoDS_Explorer(TopoDS_Shape^ S, TopAbs_ShapeEnum ToFind, TopAbs_ShapeEnum ToAvoid, bool cumOrientation, bool cumLocation): _Shape(S), _ToFind(ToFind), _ToAvoid(ToAvoid), _CumOrientation(cumOrientation), _CumLocation(cumLocation){}// 实现 IEnumerable 接口的 GetEnumerator 方法virtual Collections::Generic::IEnumerator<TopoDS_Shape^>^ GetEnumerator() sealed = Collections::Generic::IEnumerable<TopoDS_Shape^>::GetEnumerator{return gcnew TopoDS_ShapeEnumerator(this);}// 实现 IEnumerable 接口的 EnumerableGetEnumerator 方法virtual Collections::IEnumerator^ EnumerableGetEnumerator() sealed = Collections::IEnumerable::GetEnumerator{return GetEnumerator();}private:// 定义 TopoDS_ShapeEnumerator 结构,用于遍历拓扑形状ref struct TopoDS_ShapeEnumerator : public Collections::Generic::IEnumerator<TopoDS_Shape^>{private:std::stack<::TopoDS_Iterator*>* _iteratorStack; // 迭代器栈const ::TopoDS_Shape* _Shape; // 拓扑形状指针::TopAbs_ShapeEnum _ToFind; // 要查找的形状类型::TopAbs_ShapeEnum _ToAvoid; // 要避免的形状类型bool _CumOrientation; // 是否累积方向bool _CumLocation; // 是否累积位置bool _Initialized; // 是否已初始化internal:// 构造函数TopoDS_ShapeEnumerator(const TopoDS_Explorer^ explorer): _iteratorStack(nullptr), _Initialized(false){_Shape = explorer->_Shape->NativeInstance;_ToFind = (::TopAbs_ShapeEnum)explorer->_ToFind;_ToAvoid = (::TopAbs_ShapeEnum)explorer->_ToAvoid;_CumOrientation = explorer->_CumOrientation;_CumLocation = explorer->_CumLocation;}public:// 获取当前形状property TopoDS_Shape^ Current {virtual TopoDS_Shape^ get() {::TopoDS_Shape* _result = new ::TopoDS_Shape(_iteratorStack->top()->Value());return gcnew TopoDS_Shape(_result);}};// 获取当前基类对象property Object^ CurrentBase{virtual Object^ get() sealed = Collections::IEnumerator::Current::get{return Current;}};// 移动到下一个形状virtual bool MoveNext(){if (!_Initialized)return _Init();if (_iteratorStack->empty())return false;_iteratorStack->top()->Next();return _FindNext();}// 查找下一个形状bool _FindNext(){// 没有更多元素if (_iteratorStack->empty())return false;if (!_iteratorStack->top()->More()){// 当前迭代器为空delete _iteratorStack->top();_iteratorStack->pop();return MoveNext();}while (_iteratorStack->top()->More()){auto shape = _iteratorStack->top()->Value();auto shapeType = shape.ShapeType();if (shapeType == _ToFind)return true;if (LESSCOMPLEX(_ToFind, shapeType) && !AVOID(_ToAvoid, shapeType)){_iteratorStack->push(new ::TopoDS_Iterator(shape, _CumOrientation, _CumLocation));return _FindNext();}}return false;}// 重置迭代器virtual void Reset(){throw gcnew NotImplementedException();}// 析构函数virtual ~TopoDS_ShapeEnumerator(){while (!_iteratorStack->empty()){delete _iteratorStack->top();_iteratorStack->pop();}delete _iteratorStack;}private:// 初始化迭代器bool _Init(){_iteratorStack = new std::stack<::TopoDS_Iterator*>();if (_Shape == nullptr)return false;if (_ToFind == TopAbs_SHAPE)return false;auto shapeType = _Shape->ShapeType();if (LESSCOMPLEX(shapeType, _ToFind)){// 第一个形状比较简单,没有找到的必要return false;}else if (SAMETYPE(shapeType, _ToFind)){return false;}// 初始化第一级_Initialized = true;_iteratorStack->push(new ::TopoDS_Iterator(*_Shape, _CumOrientation, _CumLocation));return _FindNext();}};};}}
}

这段代码定义了一个名为 TopoDS_Explorer 的类,用于遍历拓扑形状。该类实现了 IEnumerable<TopoDS_Shape^> 接口,可以通过 foreach 循环来遍历形状。同时,利用了 C++/CLI 中的迭代器来实现形状的深度优先搜索遍历。

17

#include "ManagedPCH.h" // 包含预编译头文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System::Runtime::InteropServices; // 使用 System.Runtime.InteropServices 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{// 定义 TriangulationData 类,用于存储三角化数据public ref class TriangulationData sealed{public:// 索引数组属性property array<int>^ Indices{array<int>^ get(){return _Indices;}}// 顶点数组属性property array<Macad::Occt::Pnt>^ Vertices{ array<Macad::Occt::Pnt>^ get(){return _Vertices;} }// 法向量数组属性property array<Macad::Occt::Dir>^ Normals{ array<Macad::Occt::Dir>^ get(){return _Normals;} }// 三角形数量属性property int TriangleCount{int get(){return _Indices->Length / 3;}}// 构造函数TriangulationData(array<int>^ indices, array<Macad::Occt::Pnt>^ vertices, array<Macad::Occt::Dir>^ normals){_Indices = indices;_Vertices = vertices;_Normals = normals;}private:array<int>^ _Indices; // 索引数组array<Macad::Occt::Pnt>^ _Vertices; // 顶点数组array<Macad::Occt::Dir>^ _Normals; // 法向量数组};// 定义 TriangulationHelper 类,用于处理三角化操作public ref class TriangulationHelper sealed{public:// 获取三角化数据static TriangulationData^ GetTriangulation(Macad::Occt::TopoDS_Shape^ brepShape, bool getNormals){auto shape = *brepShape->NativeInstance;// 确保所有形状都有网格if (::BRepTools::Triangulation(shape, Precision::Infinite()) == Standard_False){::BRepMesh_IncrementalMesh aMesher(shape, 0.1);if(!aMesher.IsDone())return nullptr;}// 计算元素数量bool hasNormals = true;int triangleCount = 0;int vertexCount = 0;for(::TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()){::TopLoc_Location location;auto triangulation = ::BRep_Tool::Triangulation(::TopoDS::Face(exp.Current()), location);if (triangulation.IsNull())continue;if(getNormals && !triangulation->HasNormals()){Poly::ComputeNormals( triangulation );}triangleCount += triangulation->NbTriangles();vertexCount += triangulation->NbNodes();hasNormals &= triangulation->HasNormals();}if(triangleCount == 0 || vertexCount == 0)return nullptr;// 创建数组auto vertexArray = gcnew array<Pnt>(vertexCount);pin_ptr<Pnt> vertices_pinnedptr = &vertexArray[0];gp_Pnt* vertices = reinterpret_cast<gp_Pnt*>(vertices_pinnedptr);array<Dir>^ normalsArray = nullptr;pin_ptr<Dir> normals_pinnedptr= nullptr;gp_Dir* normals = nullptr;if(getNormals && hasNormals){normalsArray = gcnew array<Dir>(vertexCount);normals_pinnedptr = &normalsArray[0];normals = reinterpret_cast<gp_Dir*>(normals_pinnedptr);}auto indexArray = gcnew array<int>(triangleCount * 3);pin_ptr<int> indices_pinnedptr = &indexArray[0];int* indices = indices_pinnedptr;int indexOffset = 0;// 复制元素for (::TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()){::TopLoc_Location location;auto triangulation = ::BRep_Tool::Triangulation(::TopoDS::Face(exp.Current()), location);if (triangulation.IsNull())continue;const auto trsf = location.Transformation();auto orientation = exp.Current().Orientation();// 复制顶点for (int nodeIndex = 1; nodeIndex <= triangulation->NbNodes(); nodeIndex++){*vertices = triangulation->Node(nodeIndex).Transformed(trsf);vertices++;}if(getNormals && hasNormals){// 复制法向量const auto trsf = location.Transformation();for (int nrmlIndex = 1; nrmlIndex <= triangulation->NbNodes(); nrmlIndex++){*normals = triangulation->Normal(nrmlIndex);normals->Transform(trsf);if(orientation == ::TopAbs_Orientation::TopAbs_REVERSED){normals->Reverse();}normals++;}}// 复制索引const auto correctedIndexOffset = indexOffset - 1; // 更正下限,这不是0!int triIndices[3];for (int triangleIndex = 1; triangleIndex <= triangulation->NbTriangles(); triangleIndex++){const ::Poly_Triangle triangle = triangulation->Triangle(triangleIndex);if (exp.Current().Orientation() == TopAbs_REVERSED){triangle.Get(triIndices[0], triIndices[2], triIndices[1]);} else {triangle.Get(triIndices[0], triIndices[1], triIndices[2]);}// 使用面偏移复制indices[0] = triIndices[0] + correctedIndexOffset;indices[1] = triIndices[1] + correctedIndexOffset;indices[2] = triIndices[2] + correctedIndexOffset;indices += 3;}indexOffset += triangulation->NbNodes();}// 返回return gcnew TriangulationData(indexArray, vertexArray, normalsArray);}// 从三角化数据创建面static Macad::Occt::TopoDS_Face^ CreateFaceFromTriangulation(TriangulationData^ triangulationData){auto vertexCount = triangulationData->Vertices->Length;auto triangleCount = (triangulationData->Indices != nullptr ? triangulationData->Indices->Length : vertexCount) / 3;Handle(::Poly_Triangulation) triangulation = new ::Poly_Triangulation(vertexCount, triangleCount, false);// 复制顶点pin_ptr<Pnt> vertices_pinnedptr = &triangulationData->Vertices[0];gp_Pnt* vertices = reinterpret_cast<gp_Pnt*>(vertices_pinnedptr);for(int i = 1; i<=vertexCount; i++, vertices++) // 注意:节点数组从1开始{triangulation->SetNode(i, *vertices);}// 复制索引if(triangulationData->Indices != nullptr){pin_ptr<int> indices_pinnedptr = &triangulationData->Indices[0];int* indices = indices_pinnedptr;for(int index = 1; index<=triangleCount; index++, indices+=3) // 注意:三角形数组从1开始{triangulation->SetTriangle(index, Poly_Triangle(*indices+1, *(indices+1)+1, *(indices+2)+1)); // 更正下限,OCCT 需要这个为1!}}else{// 创建索引int index = 1;for(int triangle = 1; triangle<=triangleCount; triangle++, index+=3) // 注意:三角形数组从1开始{triangulation->SetTriangle(triangle, Poly_Triangle(index, index+1, index+2));}}// 创建形状::BRep_Builder builder;::TopoDS_Face face;builder.MakeFace(face);::BRepMesh_ShapeTool::AddInFace(face, triangulation);return gcnew Macad::Occt::TopoDS_Face(new ::TopoDS_Face(face));}};} // namespace Helper 结束} // namespace Occt 结束
} // namespace Macad 结束

上面的代码实现了两个帮助类 TriangulationDataTriangulationHelper,用于处理三角化操作。TriangulationData 类用于存储三角化数据,TriangulationHelper 类提供了获取三角化数据和从三角化数据创建面的功能。

18

#include "ManagedPCH.h" // 包含预编译头文件
#include <Standard_Version.hxx> // 包含 OpenCASCADE 版本文件#using "Macad.Occt.dll" as_friend // 引用 Macad.Occt.dll 库using namespace System; // 使用 System 命名空间
using namespace System::Runtime::InteropServices; // 使用 System.Runtime.InteropServices 命名空间namespace Macad // Macad 命名空间开始
{namespace Occt // Occt 命名空间开始{namespace Helper // Helper 命名空间开始{// 定义 Version 类,用于获取 OpenCASCADE 版本信息public ref class Version sealed{public:// 获取主版本号static property int Major{int get(){return OCC_VERSION_MAJOR;}}// 获取次版本号static property int Minor{int get(){return OCC_VERSION_MINOR;}}// 获取维护版本号static property int Maintenance{int get(){return OCC_VERSION_MAINTENANCE;}}// 获取开发版本号static property String^ Development{String^ get(){#ifdef OCC_VERSION_DEVELOPMENTreturn gcnew String( OCC_VERSION_DEVELOPMENT );#elsereturn gcnew String("");#endif;}}};} // namespace Helper 结束} // namespace Occt 结束
} // namespace Macad 结束

上面的代码定义了一个名为 Version 的帮助类,用于获取 OpenCASCADE 版本信息。该类包含了四个静态属性,分别用于获取主版本号、次版本号、维护版本号和开发版本号。

19

#include "solve.h" // 包含头文件 solve.h,其中可能包含了函数声明或其他必要的声明#include <cmath> // 包含数学函数的标准库
#include <stdlib.h> // 包含标准库的头文件,可能用于内存分配和其他操作
#include <sstream> // 包含字符串流的标准库using namespace std; // 使用标准命名空间// 计算两条线段平行的误差
double ParallelError(std::vector<double> &parms)
{double dx = parms[2] - parms[0]; // 计算第一条线段的 x 轴长度double dy = parms[3] - parms[1]; // 计算第一条线段的 y 轴长度double dx2 = parms[6] - parms[4]; // 计算第二条线段的 x 轴长度double dy2 = parms[7] - parms[5]; // 计算第二条线段的 y 轴长度double hyp1=sqrt(dx*dx+dy*dy); // 计算第一条线段的长度double hyp2=sqrt(dx2*dx2+dy2*dy2); // 计算第二条线段的长度dx=dx/hyp1; // 归一化第一条线段的 x 轴长度dy=dy/hyp1; // 归一化第一条线段的 y 轴长度dx2=dx2/hyp2; // 归一化第二条线段的 x 轴长度dy2=dy2/hyp2; // 归一化第二条线段的 y 轴长度double temp = dy*dx2-dx*dy2; // 计算两条线段间的误差return (temp)*(temp)*1000; // 返回误差的平方乘以 1000
}// 计算两条线段垂直的误差
double PerpendicularError(std::vector<double> &parms)
{// 同上,计算两条线段的长度和归一化double dx = parms[2] - parms[0];double dy = parms[3] - parms[1];double dx2 = parms[6] - parms[4];double dy2 = parms[7] - parms[5];double hyp1=sqrt(dx*dx+dy*dy);double hyp2=sqrt(dx2*dx2+dy2*dy2);dx=dx/hyp1;dy=dy/hyp1;dx2=dx2/hyp2;dy2=dy2/hyp2;double temp = dx*dx2+dy*dy2;// 乘以 10 而不是 1000,提高结果的稳定性return (temp)*(temp)*10;
}// 计算点与线段中点之间的误差
double PointOnLineMidpointError(std::vector<double> &parms)
{// 计算线段中点与给定点之间的误差double dx = parms[4] - parms[0];double dy = parms[5] - parms[1];double dx2 = parms[2] - parms[4];double dy2 = parms[3] - parms[5];double e1 = dx2 - dx;double e2 = dy2 - dy;double temp = e1*e1 + e2 * e2;return temp;
}// 计算保持水平对齐的误差
double HorizontalError(std::vector<double> &parms)
{double ody = parms[3] - parms[1];return ody*ody*1000;
}// 计算保持垂直对齐的误差
double VerticalError(std::vector<double> &parms)
{double odx = parms[2] - parms[0];return odx*odx*1000;
}// 计算两点之间的误差
double PointOnPointError(std::vector<double> &parms)
{// 计算两点之间的欧几里得距离的平方double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];return dx*dx + dy*dy;
}// 计算两点之间指定距离的误差
double P2PDistanceError(std::vector<double> &parms)
{// 计算两点之间的欧几里得距离与给定距离之间的误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double d = parms[4];double err = dx*dx + dy*dy - d * d;return err*err;
}// 计算两点之间指定水平距离的误差
double P2PDistanceHorzError(std::vector<double> &parms)
{// 计算两点之间的水平距离与给定距离之间的误差double dx = parms[0] - parms[2];double d = parms[4];double err = dx*dx - d * d;return err*err;
}// 计算两点之间指定垂直距离的误差
double P2PDistanceVertError(std::vector<double> &parms)
{// 计算两点之间的垂直距离与给定距离之间的误差double dy = parms[1] - parms[3];double d = parms[4];double err = dy*dy - d * d;return err * err;
}// 计算点与直线之间的误差
double PointOnLineError(std::vector<double> &parms)
{// 计算点到直线的垂线距离的平方作为误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double m=dy/dx; // 斜率double n=dx/dy; // 1/斜率if(m<=1 && m>=-1){// 根据点的 x 坐标计算期望的 y 坐标double Ey=parms[1]+m*(parms[4]-parms[0]);return (Ey-parms[5])*(Ey-parms[5]);}else{// 根据点的 y 坐标计算期望的 x 坐标double Ex=parms[0]+n*(parms[5]-parms[1]);return (Ex-parms[4])*(Ex-parms[4]);}
}// 计算点与线段之间的距离误差
double P2LDistanceE(double lx, double ly, double dx, double dy, double px, double py)
{// 计算点到直线的距离double t=-(lx*dx-px*dx+ly*dy-py*dy)/(dx*dx+dy*dy);double Xint=lx+dx*t;double Yint=ly+dy*t;double temp= sqrt((px - Xint)*(px - Xint)+(py - Yint)*(py - Yint));return temp;
}// 计算点与线段之间的距离误差
double P2LDistanceError(std::vector<double> &parms)                      
{// 计算点到线段的距离与给定半径之间的误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double radsq = parms[6] * parms[6];double temp= P2LDistanceE(parms[0],parms[1],dx,dy,parms[4],parms[5]) - sqrt(radsq);return temp*temp*100;
}// 计算线段与椭圆之间的接触误差
double EllipseTangentError(std::vector<double> &parms)                      
{// 同上,计算线段与椭圆之间的接触误差double ex = parms[4];double ey = parms[5];double majr = parms[6];double minr = parms[7];double rot = parms[8];if(minr > majr){double temp = majr;majr = minr;minr = temp;rot += M_PI/2;}double t = majr;majr = minr;minr = t;rot = -rot;double lx1 = cos(rot)*(parms[0]-ex) - sin(rot)*(parms[1]-ey);double ly1 = sin(rot)*(parms[0]-ex) + cos(rot)*(parms[1]-ey);double lx2 = cos(rot)*(parms[2]-ex) - sin(rot)*(parms[3]-ey);double ly2 = sin(rot)*(parms[2]-ex) + cos(rot)*(parms[3]-ey);double ldx = lx1 - lx2;double ldy = ly1 - ly2;double g = (2 * ldx * lx1)/majr/majr+(2 * ldy * ly1)/minr / minr;double det = g*g-4 * (ldx*ldx/majr/majr+ldy*ldy/minr/minr) * (lx1*lx1/majr/majr+ly1*ly1/minr/minr-1);return det * det * 10;
}// 计算点与垂直线段之间的距离误差
double P2LDistanceVertError(std::vector<double> &parms)
{// 计算点到垂直线段的距离与给定半径之间的误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double t=(parms[4]- parms[0])/dx;double Yint=parms[1]+dy*t;double temp= fabs((parms[5] - Yint)) - parms[6];return temp*temp;
}// 计算点与水平线段之间的距离误差
double P2LDistanceHorzError(std::vector<double> &parms)
{// 计算点到水平线段的距离与给定半径之间的误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double t=(parms[5]- parms[1])/dy;double Xint=parms[0]+dx*t;double temp= fabs((parms[4] - Xint)) - parms[6];return temp*temp/10;
}// 计算线段长度的误差
double LineLengthError(std::vector<double> &parms)
{// 计算线段长度与给定长度之间的误差double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double temp= sqrt(dx*dx+dy*dy) - parms[4];return temp*temp*100;
}// 计算两线段长度相等的误差
double EqualLengthError(std::vector<double> &parms)
{// 计算两线段长度的差值的平方double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double dx2 = parms[4] - parms[6];double dy2 = parms[5] - parms[7];double temp = sqrt(dx*dx+dy*dy) -  sqrt(dx2*dx2+dy2*dy2);return temp*temp;
}// 计算两标量值相等的误差
double EqualScalarError(std::vector<double> &parms)
{// 计算两个标量值之间的差值的平方double temp= parms[0] - parms[1];return temp*temp;
}// 计算点与圆弧角度之间的误差
double PointOnArcAngleError(std::vector<double> &parms)
{// 计算点到圆弧的距离误差double a1x = sin(parms[5]) * parms[4] + parms[2];double a1y = cos(parms[5]) * parms[4] + parms[3];double dx = parms[0] - a1x;double dy = parms[1] - a1y;return dx*dx + dy*dy;
}// 计算两圆弧角度之间的误差
double ArcAngleOnArcAngleError(std::vector<double> &parms)
{// 计算两圆弧之间的距离误差double a1x = sin(parms[3]) * parms[2] + parms[0];double a1y = cos(parms[3]) * parms[2] + parms[1];double a2x = sin(parms[7]) * parms[6] + parms[4];double a2y = cos(parms[7]) * parms[6] + parms[5];double dx = a2x - a1x;double dy = a2y - a1y;return dx*dx + dy*dy;
}// 计算共线误差
double ColinearError(std::vector<double>& parms)
{// 计算两线段的斜率double dx = parms[2] - parms[0];double dy = parms[3] - parms[1];double m=dy/dx;double n=dx/dy;double error=0;if(m<=1 && m>-1){// 计算第一条线段上第二条线段两端点在第一条线段上的投影点与其真实位置之间的误差double Ey=parms[1]+m*(parms[4]-parms[0]);error+=(Ey-parms[5])*(Ey-parms[5]);Ey=parms[1]+m*(parms[6]-parms[0]);error+=(Ey-parms[7])*(Ey-parms[7]);}else{// 计算第一条线段上第二条线段两端点在第一条线段上的投影点与其真实位置之间的误差double Ex=parms[0]+n*(parms[5]-parms[1]);error+=(Ex-parms[4])*(Ex-parms[4]);Ex=parms[0]+n*(parms[7]-parms[1]);error+=(Ex-parms[6])*(Ex-parms[6]);}return error;
}// 计算与给定角度垂直的直线误差
double LinePerpToAngleError(std::vector<double>& parms)
{// 计算线的方向向量与给定角度向量的夹角的平方double dx = parms[0] - parms[2];double dy = parms[1] - parms[3];double dx2 = sin(parms[4]);double dy2 = cos(parms[4]);double hyp1=sqrt(dx*dx+dy*dy);double hyp2=sqrt(dx2*dx2+dy2*dy2);dx=dx/hyp1;dy=dy/hyp1;dx2=dx2/hyp2;dy2=dy2/hyp2;double temp = dx*dx2+dy*dy2;return (temp)*(temp)*1000;
}// 计算点的垂直距离误差
double PointVerticalDistanceError(std::vector<double> &parms)
{// 计算点的垂直距离与给定距离之间的误差double err = fabs(parms[1]) - fabs(parms[2]);return err*err;
}// 计算点的水平距离误差
double PointHorizontalDistanceError(std::vector<double> &parms)
{// 计算点的水平距离与给定距离之间的误差double err = fabs(parms[0]) - fabs(parms[2]);return err*err;
}// 计算内部角度误差
double InternalAngleError(std::vector<double>& parms)
{// 计算两向量的夹角与给定角度之间的误差double dx = parms[2] - parms[0];double dy = parms[3] - parms[1];double dx2 = parms[6] - parms[4];double dy2 = parms[7] - parms[5];double angleP = parms[8];double hyp1=_hypot(dx,dy);double hyp2=_hypot(dx2,dy2);dx=dx/hyp1;dy=dy/hyp1;dx2=dx2/hyp2;dy2=dy2/hyp2;double temp = dx*dx2+dy*dy2;double temp2 = cos(angleP);return (temp-temp2)*(temp-temp2);
}// 计算外部角度误差
double ExternalAngleError(std::vector<double>& parms)
{// 计算两向量的夹角与给定角度之间的误差double dx = parms[2] - parms[0];double dy = parms[3] - parms[1];double dx2 = parms[6] - parms[4];double dy2 = parms[7] - parms[5];double angleP = parms[8];double hyp1=_hypot(dx,dy);double hyp2=_hypot(dx2,dy2);dx=dx/hyp1;dy=dy/hyp1;dx2=dx2/hyp2;dy2=dy2/hyp2;double temp = dx*dx2-dy*dy2;double temp2 = cos(M_PI-angleP);return (temp-temp2)*(temp-temp2);
}

这段代码定义了一系列函数,用于计算几何形状之间的误差。这些函数被设计用于优化几何形状的拟合,例如线段、圆弧、椭圆等。下面是每个函数的详细总结:

  1. ParallelError: 计算两条线段平行的误差。
  2. PerpendicularError: 计算两条线段垂直的误差。
  3. PointOnLineMidpointError: 计算点在线段中点的误差。
  4. HorizontalError: 计算水平线段的误差。
  5. VerticalError: 计算垂直线段的误差。
  6. PointOnPointError: 计算两个点重合的误差。
  7. P2PDistanceError: 计算两点之间距离的误差。
  8. P2PDistanceHorzError: 计算水平距离的误差。
  9. P2PDistanceVertError: 计算垂直距离的误差。
  10. PointOnLineError: 计算点在直线上的误差。
  11. P2LDistanceError: 计算点到线段距离的误差。
  12. EllipseTangentError: 计算椭圆与线段的接触误差。
  13. P2LDistanceVertError: 计算点到垂直线段距离的误差。
  14. P2LDistanceHorzError: 计算点到水平线段距离的误差。
  15. LineLengthError: 计算线段长度的误差。
  16. EqualLengthError: 计算两线段长度相等的误差。
  17. EqualScalarError: 计算两标量值相等的误差。
  18. PointOnArcAngleError: 计算点在圆弧上的角度误差。
  19. ArcAngleOnArcAngleError: 计算两圆弧角度之间的误差。
  20. ColinearError: 计算共线误差。
  21. LinePerpToAngleError: 计算线段垂直于给定角度的误差。
  22. PointVerticalDistanceError: 计算点的垂直距离误差。
  23. PointHorizontalDistanceError: 计算点的水平距离误差。
  24. InternalAngleError: 计算内部角度误差。
  25. ExternalAngleError: 计算外部角度误差。

每个函数都有不同的计算逻辑,但都旨在衡量拟合几何形状的质量。

20

#include "solve.h"  // 包含头文件 solve.husing namespace System::Collections::Generic;  // 使用泛型集合命名空间
using namespace System::Diagnostics;  // 使用诊断命名空间#define VALUEPTR(x) (parameters[x]->Pointer)  // 定义宏,用于获取参数指针namespace Macad
{namespace SketchSolve{public enum class ConstraintType  // 定义约束类型枚举{PointOnPoint = constraintType::pointOnPoint,  // 点在点上约束PointToLine = constraintType::pointToLine,  // 点到线约束// 其他约束类型...};//--------------------------------------------------------------------------------------------------public enum class Result  // 定义求解结果枚举{Success = 0,  // 成功NoSolution = 1  // 无解};//--------------------------------------------------------------------------------------------------public enum class Usage  // 定义参数使用方式枚举{Variable,  // 变量Constant,  // 常量Immutable  // 不可变};//--------------------------------------------------------------------------------------------------public ref class Parameter  // 参数类{public:double Value = 0.0;  // 参数值,默认为0.0Usage Usage = Usage::Variable;  // 参数使用方式,默认为变量int PointKey = -1;  // 点键,默认为-1double* Pointer;  // 指向参数值的指针};//--------------------------------------------------------------------------------------------------public value struct Point  // 点结构体{int X;  // X 坐标int Y;  // Y 坐标point ToNative(List<Parameter^>^ parameters)  // 将参数列表转换为本地结构体{point p;p.x = VALUEPTR(X);  // 获取 X 坐标的指针并赋值给 p.xp.y = VALUEPTR(Y);  // 获取 Y 坐标的指针并赋值给 p.yreturn p;}};//--------------------------------------------------------------------------------------------------public value struct Line  // 线段结构体{Point P1;  // 起点Point P2;  // 终点line ToNative(List<Parameter^>^ parameters)  // 将参数列表转换为本地结构体{line l;l.p1 = P1.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取起点l.p2 = P2.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取终点return l;}};//--------------------------------------------------------------------------------------------------public value struct Circle  // 圆结构体{Point Center;  // 圆心int Radius;  // 半径circle ToNative(List<Parameter^>^ parameters)  // 将参数列表转换为本地结构体{circle c;c.center = Center.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取圆心c.rad = VALUEPTR(Radius);  // 获取半径的指针并赋值给 c.radreturn c;}};//--------------------------------------------------------------------------------------------------public value struct Arc  // 圆弧结构体{Point Start;  // 起始点Point End;  // 终点Point Center;  // 圆心arc ToNative(List<Parameter^>^ parameters)  // 将参数列表转换为本地结构体{arc a;a.start = Start.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取起始点a.end = End.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取终点a.center = Center.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取圆心return a;}};//--------------------------------------------------------------------------------------------------[DebuggerDisplay("{Type,nq}")]public value struct Constraint  // 约束结构体{ConstraintType Type;  // 约束类型Point Point1;  // 第一个点Point Point2;  // 第二个点Line Line1;  // 第一条线段Line Line2;  // 第二条线段Line SymLine;  // 对称线段Circle Circle1;  // 第一个圆Circle Circle2;  // 第二个圆Arc Arc1;  // 第一个圆弧Arc Arc2;  // 第二个圆弧int Parameter;  // 参数constraint ToNative(List<SketchSolve::Parameter^>^ parameters)  // 将参数列表转换为本地结构体{constraint cons;cons.type = static_cast<constraintType>(Type);  // 将约束类型转换为本地约束类型cons.point1 = Point1.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取第一个点cons.point2 = Point2.ToNative(parameters);  // 调用 Point 结构体的 ToNative 方法获取第二个点cons.line1 = Line1.ToNative(parameters);  // 调用 Line 结构体的 ToNative 方法获取第一条线段cons.line2 = Line2.ToNative(parameters);  // 调用 Line 结构体的 ToNative 方法获取第二条线段cons.SymLine = SymLine.ToNative(parameters);  // 调用 Line 结构体的 ToNative 方法获取对称线段cons.circle1 = Circle1.ToNative(parameters);  // 调用 Circle 结构体的 ToNative 方法获取第一个圆cons.circle2 = Circle2.ToNative(parameters);  // 调用 Circle 结构体的 ToNative 方法获取第二个圆cons.arc1 = Arc1.ToNative(parameters);  // 调用 Arc 结构体的 ToNative 方法获取第一个圆弧cons.arc2 = Arc2.ToNative(parameters);  // 调用 Arc 结构体的 ToNative 方法获取第二个圆弧cons.parameter = VALUEPTR(Parameter);  // 获取参数的指针并赋值给 cons.parameterreturn cons;}};//--------------------------------------------------------------------------------------------------public ref class Solver  // 求解器类{public:static Result Solve(List<Parameter^>^ parameters, List<Constraint>^ constraints, bool precise)  // 求解方法{int curVariable = 0;  // 当前变量索引int curConstant = parameters->Count - 1;  // 当前常量索引为参数数量减1// Link parameters to native arraydouble* pParameters = new double[parameters->Count];  // 创建参数值数组for each (Parameter^ parameter in parameters)  // 遍历参数列表{int index;  // 索引if (parameter->Usage == Usage::Variable)  // 如果参数使用方式为变量{index = curVariable;  // 当前索引为变量索引curVariable++;  // 变量索引加1}else  // 否则为常量{index = curConstant;  // 当前索引为常量索引curConstant--;  // 常量索引减1}parameter->Pointer = &pParameters[index];  // 将参数的指针指向参数值数组的相应位置*parameter->Pointer = parameter->Value;  // 将参数的值赋给参数值数组对应位置}// Create variable address arrayconst int numVariables = curVariable;  // 变量数量为当前变量索引double** ppParameters = new double*[numVariables];  // 创建指向参数指针的数组for (int i = 0; i < numVariables; i++)  // 遍历变量数量{ppParameters[i] = &(pParameters[i]);  // 将参数指针指向参数值数组的相应位置}// Create native constraint arrayconstraint* pConstraints = new constraint[constraints->Count];  // 创建本地约束数组for (int i = 0; i < constraints->Count; i++)  // 遍历约束列表{pConstraints[i] = constraints[i].ToNative(parameters);  // 将约束转换为本地约束并存入数组}// Call solver::Solver solver;  // 创建求解器对象const int result = solver.solve(ppParameters, numVariables, pConstraints, constraints->Count, precise ? fine : rough);  // 调用求解器求解if (result == succsess)  // 如果求解成功{// Copy result parametersfor each (Parameter^ parameter in parameters)  // 遍历参数列表{parameter->Value = *parameter->Pointer;  // 将参数值更新为指针指向的值}}// Clean updelete[] pConstraints;  // 清理约束数组内存delete[] ppParameters;  // 清理参数指针数组内存delete[] pParameters;  // 清理参数值数组内存return result == succsess ? Result::Success : Result::NoSolution;  // 返回求解结果枚举值}};}
}

这段代码定义了一个用于解决几何约束问题的 C++/CLI 接口。包括定义了几种枚举类型(约束类型、求解结果、参数使用方式)、参数类、几何元素结构体(点、线段、圆、圆弧)、约束结构体和求解器类。其中,求解器类提供了一个静态方法 Solve,用于求解几何约束问题。

21

#include "solve.h"
#include <cmath> // 包含数学函数库
#include <stdlib.h> // 包含标准库函数
#include <sstream> // 包含字符串流库using namespace std; // 使用标准命名空间Solver::Solver() // Solver类的构造函数
{}void Solver::allocate(int xLength) // 分配内存空间函数,参数为xLength
{this->xLength = xLength; // 设置成员变量xLength为传入的参数xLengthif(x.size() < (size_t)xLength) // 如果x数组的大小小于xLength{// 根据xLength分配数组内存空间x.resize(xLength);origSolution.resize(xLength);grad.resize(xLength);s.resize(xLength);xold.resize(xLength);deltaX.resize(xLength);gradnew.resize(xLength);gamma.resize(xLength);gammatDotN.resize(xLength);FirstSecond.resize(xLength);deltaXDotGammatDotN.resize(xLength);gammatDotDeltaXt.resize(xLength);NDotGammaDotDeltaXt.resize(xLength);N.resize(xLength);for(int i=0; i < xLength; i++) // 对每个数组元素进行初始化{// 初始化二维数组的每一行FirstSecond[i].resize(xLength);deltaXDotGammatDotN[i].resize(xLength);gammatDotDeltaXt[i].resize(xLength);NDotGammaDotDeltaXt[i].resize(xLength);N[i].resize(xLength);}}
}Solver::~Solver() // Solver类的析构函数
{}void Solver::deallocate() // 释放内存函数
{
}int Solver::solve(double  **xin, int xLength, constraint * cons, int consLength, int isFine) // 主要求解函数,参数为xin、xLength、cons、consLength和isFine
{// 调用实际求解函数solveIint ret = solveI(xin,xLength,cons,consLength,isFine);Unload(); // 调用Unload函数deallocate(); // 调用deallocate函数return ret; // 返回求解结果
}int Solver::solveI(double  **xin, int xLength, constraint * cons, int consLength, int isFine) // 实际求解函数,参数为xin、xLength、cons、consLength和isFine
{xsave = xin; // 将传入的参数xin赋值给类的成员变量xsaveLoad(cons,consLength,xin,xLength); // 调用Load函数加载数据xLength = GetVectorSize(); // 调用GetVectorSize函数获取向量大小allocate(xLength); // 调用allocate函数分配内存空间// 初始化x数组for(int i=0; i < xLength; i++)x[i] = GetInitialValue(i); // 调用GetInitialValue函数初始化数组元素std::stringstream cstr; // 创建字符串流对象cstrdouble convergence,pert ; // 定义两个double类型的变量// 保存初始参数for(int i=0;i<xLength;i++){origSolution[i]=x[i]; // 将当前参数值保存到origSolution数组中}if(isFine>0) convergence = XconvergenceFine; // 根据isFine的值选择收敛精度else convergence = XconvergenceRough;int ftimes=0; // 记录函数调用次数的变量double f0;f0 = GetError(); // 计算初始误差值if(f0<smallF) return succsess; // 如果初始误差值小于某个阈值,则返回成功ftimes++; // 增加函数调用次数// 计算初始梯度double norm; // 梯度向量的范数norm = 0; // 初始化范数pert = f0*pertMag; // 根据初始误差值计算扰动值// 计算梯度向量for(int j=0;j<xLength;j++){grad[j]=GetGradient(j,pert); // 获取第j个参数的梯度ftimes++; // 增加函数调用次数norm = norm+(grad[j]*grad[j]); // 更新梯度向量的范数}norm = sqrt(norm); // 计算梯度向量的范数// 计算N的范数// 初始化N和sfor(int i=0;i<xLength;i++){for(int j=0;j<xLength;j++){if(i==j){N[i][j]=1; // 对角元素设为1s[i]=-grad[i]; // 计算初始搜索向量}else N[i][j]=0; // 非对角元素设为0}}double fnew;fnew=f0+1; // 使fnew大于folddouble alpha=1; // 初始搜索向量乘数double fold; // 上一次迭代的误差值for(int i=0;i<xLength;i++){xold[i]=x[i];//将上次的参数值保存到xold数组中}// 主要的线搜索过程// 初始位置设为alpha1alpha1=0;f1 = f0;// 以alpha=1的步长作为alpha2alpha2=1;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha2*s[i];//计算新的x值}f2 = GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数// 以2*alpha2为步长作为alpha3alpha3 = alpha*2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha3*s[i];//计算新的x值}f3=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数// 缩短或延长alpha2和alpha3,直到最小值在f1>f2<f3的三元组中while(f2>f1 || f2>f3){if(f2>f1){// 如果f2大于f1,则缩短alpha2和alpha3alpha3=alpha2;f3=f2;alpha2=alpha2/2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha2*s[i];//计算新的x值}f2=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数}else if(f2>f3){// 如果f2大于f3,则延长alpha2和alpha3alpha2=alpha3;f2=f3;alpha3=alpha3*2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha3*s[i];//计算新的x值}f3=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数}}// 计算二次近似的最小f的alphaalphaStar= alpha2+((alpha2-alpha1)*(f1-f3))/(3*(f1-2*f2+f3));// 确保新的alphaStar在bracket中if(alphaStar>alpha3 || alphaStar<alpha1) alphaStar=alpha2;if(alphaStar!=alphaStar){alphaStar=.001;//修复nan问题}// 将值设置为alphaStarfor(int i=0;i<xLength;i++){x[i]=xold[i]+alphaStar*s[i];//计算新的x值}fnew=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数fold=fnew; // 更新上一次的误差值// 主循环double bottom=0; // 底部值double deltaXtDotGamma; // deltaX转置乘以gammadouble gammatDotNDotGamma=0; // gamma转置乘以N乘以gammadouble firstTerm=0; // 第一项double deltaXnorm=1; // deltaX的范数int iterations=1; // 迭代次数int steps;// 计算deltaXfor(int i=0;i<xLength;i++){deltaX[i]=x[i]-xold[i];//计算Hessian更新的x差}double maxIterNumber = MaxIterations * xLength; // 最大迭代次数while(deltaXnorm>convergence && fnew>smallF && iterations<maxIterNumber){// 主循环bottom=0; // 初始化底部值deltaXtDotGamma = 0; // 初始化deltaXtDotGammapert = fnew*pertMag; // 计算扰动值if(pert<pertMin) pert = pertMin;for(int i=0;i<xLength;i++){// 计算新的梯度向量gradnew[i]= GetGradient(i,pert);ftimes++; // 增加函数调用次数// 计算梯度变化量gamma[i]=gradnew[i]-grad[i];bottom+=deltaX[i]*gamma[i];deltaXtDotGamma += deltaX[i]*gamma[i];}if (bottom==0) bottom=.0000000001; // 保证底部不为0// 计算所有(1xn).(nxn)矩阵for(int i=0;i<xLength;i++){gammatDotN[i]=0;for(int j=0;j<xLength;j++){gammatDotN[i]+=gamma[j]*N[i][j];//这是gammatDotN转置}}// 计算所有(1xn).(nx1)矩阵gammatDotNDotGamma=0;for(int i=0;i<xLength;i++){gammatDotNDotGamma+=gammatDotN[i]*gamma[i];}// 计算第一项firstTerm=0;firstTerm=1+gammatDotNDotGamma/bottom;// 计算所有(nx1).(1xn)矩阵for(int i=0;i<xLength;i++){for(int j=0;j<xLength;j++){FirstSecond[i][j]=((deltaX[j]*deltaX[i])/bottom)*firstTerm;deltaXDotGammatDotN[i][j]=deltaX[i]*gammatDotN[j];gammatDotDeltaXt[i][j]=gamma[i]*deltaX[j];}}// 计算所有(nxn).(nxn)矩阵for(int i=0;i<xLength;i++){for(int j=0;j<xLength;j++){NDotGammaDotDeltaXt[i][j]=0;for(int k=0;k<xLength;k++){NDotGammaDotDeltaXt[i][j]+=N[i][k]*gammatDotDeltaXt[k][j];}}}// 计算BFGS更新的Nfor(int i=0;i<xLength;i++){for(int j=0;j<xLength;j++){N[i][j]=N[i][j]+FirstSecond[i][j]-(deltaXDotGammatDotN[i][j]+NDotGammaDotDeltaXt[i][j])/bottom;}}// 计算sfor(int i=0;i<xLength;i++){s[i]=0;for(int j=0;j<xLength;j++){s[i]+=-N[i][j]*gradnew[j];}}alpha=1; // 初始化搜索向量乘数// 将最新的值复制到xoldfor(int i=0;i<xLength;i++){xold[i]=x[i];//将上次的参数值复制到xold}steps=0;// 主线搜索// 初始位置设为alpha1alpha1=0;f1 = fnew;// 以alpha=1的步长作为alpha2alpha2=1;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha2*s[i];//计算新的x值}f2 = GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数// 以2*alpha2为步长作为alpha3alpha3 = alpha2*2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha3*s[i];//计算新的x值}f3=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数// 缩短或延长alpha2和alpha3,直到最小值在f1>f2<f3的三元组中steps=0;while(f2>f1 || f2>f3){if(f2>f1){// 如果f2大于f1,则缩短alpha2和alpha3alpha3=alpha2;f3=f2;alpha2=alpha2/2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha2*s[i];//计算新的x值}f2=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数}else if(f2>f3){// 如果f2大于f3,则延长alpha2和alpha3alpha2=alpha3;f2=f3;alpha3=alpha3*2;for(int i=0;i<xLength;i++){x[i]=xold[i]+alpha3*s[i];//计算新的x值}f3=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数}steps=steps+1;}// 获取二次近似的最小f的alphaalphaStar= alpha2+((alpha2-alpha1)*(f1-f3))/(3*(f1-2*f2+f3));// 确保新的alphaStar在bracket中if(alphaStar>=alpha3 || alphaStar<=alpha1){alphaStar=alpha2;}if(alphaStar!=alphaStar) alphaStar=0;// 将值设置为alphaStarfor(int i=0;i<xLength;i++){x[i]=xold[i]+alphaStar*s[i];//计算新的x值}fnew=GetError(); // 计算新的误差值ftimes++; // 增加函数调用次数deltaXnorm=0;for(int i=0;i<xLength;i++){deltaX[i]=x[i]-xold[i];//计算Hessian更新的x差deltaXnorm+=deltaX[i]*deltaX[i];grad[i]=gradnew[i];}deltaXnorm=sqrt(deltaXnorm); // 计算deltaX的范数iterations++; // 增加迭代次数}// 输出调试信息#ifdef DEBUGfor(int i=0;i<xLength;i++){cstr<<"Parameter("<<i<<"): "<<x[i]<<endl;}cstr<<"Fnew: "<<fnew<<endl;cstr<<"Number of Iterations: "<<iterations<<endl;cstr<<"Number of function calls: "<<ftimes<<endl;debugprint(cstr.str());cstr.clear();#endif// 返回结果double validSolution;if(isFine==1) validSolution=validSolutionFine;else validSolution=validSoltuionRough;if(fnew<validSolution){return succsess;}else{// 替换错误的参数值为上次的结果for(int i=0;i<xLength;i++){x[i]=origSolution[i];}return noSolution;}}

这段代码似乎是用于解决优化问题的求解器,可能使用了BFGS(Broyden–Fletcher–Goldfarb–Shanno)方法。以下是每个函数的作用总结:

  • Solver::allocate(int xLength): 根据给定的长度分配用于求解器的数组内存空间。
  • Solver::solve(double **xin, int xLength, constraint * cons, int consLength, int isFine): 主要函数,启动优化过程。
  • Solver::solveI(double **xin, int xLength, constraint * cons, int consLength, int isFine): 实现优化算法。它通过BFGS方法进行迭代,以最小化误差函数(GetError())。
  • Solver::deallocate(): 释放求解器使用的内存。
  • 主要优化循环中调用其他辅助函数来计算梯度、更新参数和执行线搜索。

代码似乎还包括调试语句(#ifdef DEBUG)以打印中间结果和调试信息。此外,它还跟踪了在优化过程中执行的函数调用次数和迭代次数。

22

#include "solve.h"
#include <cmath>
#include <stdlib.h>
#include <sstream>using namespace std;void SolveImpl::LoadDouble(std::vector<std::pair<varLocation,void*> > &mylist, double *d, int c)
{// 如果参数已经在参数列表中,则返回if(parms[d]){// 许多变量可能已经在向量中,必须检查并重新映射if(mapset.find(d) != mapset.end()){// 获取参数的位置std::pair<varLocation,void*> tparm = mapparms[d];// 将参数位置添加到列表中mylist.push_back(tparm);// 如果参数是向量,则将其索引添加到相应的向量映射中if(tparm.first == Vector)vecmap[(size_t)tparm.second].push_back(c);return;}// 将参数添加到新的向量位置,并将其位置映射到参数中vecmap[next_vector].push_back(c);std::pair<varLocation,void*> newloc(Vector,(void*)next_vector++);mylist.push_back(newloc);mapparms[d] = newloc;mapset.insert(d);// 将参数添加到参数向量中myvec.push_back(d);return;}// 将参数添加到静态位置mylist.push_back(std::pair<varLocation,void*>(Static,d));
}void SolveImpl::LoadPoint(std::vector<std::pair<varLocation,void*> > &mylist, point p, int c)
{// 将点的 x 和 y 坐标加载到约束条件的列表中LoadDouble(mylist,p.x,c);LoadDouble(mylist,p.y,c);
}void SolveImpl::LoadLine(std::vector<std::pair<varLocation,void*> > &mylist,line l, int c)
{// 将线段的两个端点加载到约束条件的列表中LoadPoint(mylist,l.p1,c);LoadPoint(mylist,l.p2,c);
}void SolveImpl::LoadArc(std::vector<std::pair<varLocation,void*> > &mylist,arc a, int c)
{// 将圆弧的圆心、起始角度、终止角度和半径加载到约束条件的列表中LoadPoint(mylist,a.center,c);LoadDouble(mylist,a.startAngle,c);LoadDouble(mylist,a.endAngle,c);LoadDouble(mylist,a.rad,c);
}void SolveImpl::LoadCircle(std::vector<std::pair<varLocation,void*> > &mylist,circle c, int con)
{// 将圆的圆心和半径加载到约束条件的列表中LoadPoint(mylist,c.center,con);LoadDouble(mylist,c.rad,con);
}void SolveImpl::LoadEllipse(std::vector<std::pair<varLocation,void*> > &mylist,ellipse e, int con)
{// 将椭圆的中心、两个半径、旋转角加载到约束条件的列表中LoadPoint(mylist,e.center,con);LoadDouble(mylist,e.radone,con);LoadDouble(mylist,e.radtwo,con);LoadDouble(mylist,e.rot,con);
}// 构造函数,初始化类的成员变量和约束条件的类型
SolveImpl::SolveImpl()
{next_vector=0;pvec.resize(50);// 注册约束条件类型、依赖关系和计算误差的函数registerdependency(tangentToEllipse,line1);registerdependency(tangentToEllipse,ellipse1);registerconstraint(tangentToEllipse,EllipseTangentError);// 其他约束条件注册类似的依赖关系和误差函数// ...}SolveImpl::~SolveImpl()
{
}// 加载约束条件
void SolveImpl::Load(constraint *c, int nconstraints, double** p, int nparms)
{constraintvars.clear();myvec.clear();constrainttypes.clear();mapparms.clear();mapset.clear();next_vector=0;parms.clear();vecmap.clear();// 将参数和约束条件加载到内存中for(int i=0; i < nparms; i++){parms[p[i]] = 1;}for(int i=0; i < nconstraints; i++){Load(c[i]);}
}// 获取某个参数下的梯度误差
double SolveImpl::GetErrorForGrad(int i)
{double error = 0;for(unsigned int j = 0; j < vecmap[i].size(); j++){int cindex = (int)vecmap[i][j];error += GetError(cindex);}return error;
}// 计算某个参数的梯度
double SolveImpl::GetGradient(int i, double pert)
{double OldValue = GetElement(i);SetElement(i,OldValue-pert);double e1 = GetErrorForGrad(i);SetElement(i,OldValue+pert);double e2 = GetErrorForGrad(i);SetElement(i,OldValue);return .5*(e2-e1)/pert;
}// 获取当前参数下的总误差
double SolveImpl::GetError()
{double error = 0;for(unsigned int i=0; i < constrainttypes.size(); i++){error += GetError(i);}return error;
}// 获取指定约束条件下的误差
double SolveImpl::GetError(int i)
{int count=0;std::vector<std::pair<varLocation,void*> > tlist = constraintvars[i];std::vector<std::pair<varLocation,void*> >::iterator it3;for(it3 = tlist.begin(); it3 != tlist.end(); ++it3){std::pair<varLocation,void*> tvar = *it3;if(tvar.first == Vector)pvec[count++]=GetElement((size_t)tvar.second);elsepvec[count++] = *((double*)tvar.second);}return errors[constrainttypes[i]](pvec);
}// 加载约束条件到约束条件的列表中
void SolveImpl::Load(constraint &c)
{std::vector<std::pair<varLocation,void*> > mylist;std::vector<dependencyType>::iterator it;int count = (int)constrainttypes.size();for(unsigned int i = 0; i < dependencies[c.type].size(); i++){switch(dependencies[c.type][i]){// 根据约束类型加载对应的参数到列表中case line1: LoadLine(mylist,c.line1,count); break;case line1_p1: LoadPoint(mylist,c.line1.p1,count); break;case line1_p1_x: LoadDouble(mylist,c.line1.p1.x,count); break;case line1_p1_y: LoadDouble(mylist,c.line1.p1.y,count); break;// 其他情况类似// ...}}// 将约束条件的参数列表和类型添加到相应的向量中constraintvars.push_back(mylist);constrainttypes.push_back(c.type);
}// 将最优解传递给原始指针
void SolveImpl::Unload()
{//For every item in mapparms, copy variable from vector into pointerstd::map<double*,std::pair<varLocation,void*> >::iterator it;for(it = mapparms.begin(); it != mapparms.end(); ++it){std::pair<varLocation, void*> parm = (*it).second;double* location = (*it).first;if(parm.first != Vector)continue;*location = GetElement((size_t)parm.second);}
}// 注册约束条件及其对应的误差计算函数
void SolveImpl::registerconstraint(constraintType type,double(*error)(std::vector<double>&))
{if(errors.size() < (unsigned int)type + 1)errors.resize((unsigned int)type+1);errors[type] = error;
}// 注册约束条件及其依赖项
void SolveImpl::registerdependency(constraintType type, dependencyType d)
{if(depset.find(type) == depset.end()){if(dependencies.size() < (unsigned int)type + 1)dependencies.resize((unsigned int)type+1);depset.insert(type);}dependencies[type].push_back(d);
}// 获取参数的初始值
double SolveImpl::GetInitialValue(int i)
{return *myvec[i];
}// 获取参数向量的大小
int SolveImpl::GetVectorSize() const
{return (int)myvec.size();
}

这段代码实现了一个名为 SolveImpl 的类,用于求解一组约束条件下的最优解。以下是该类的主要成员函数的功能注释:

  1. LoadDouble 函数:将双精度浮点数加载到约束条件的列表中。
  2. LoadPoint 函数:加载点对象到约束条件的列表中。
  3. LoadLine 函数:加载线段对象到约束条件的列表中。
  4. LoadArc 函数:加载圆弧对象到约束条件的列表中。
  5. LoadCircle 函数:加载圆对象到约束条件的列表中。
  6. LoadEllipse 函数:加载椭圆对象到约束条件的列表中。
  7. SolveImpl 构造函数:初始化类的成员变量和约束条件的类型。
  8. Load 函数:加载约束条件到约束条件的列表中。
  9. GetErrorForGrad 函数:获取某个参数下的梯度误差。
  10. GetGradient 函数:计算某个参数的梯度。
  11. GetError 函数:获取当前参数下的总误差。
  12. GetError 函数(重载):获取指定约束条件下的误差。
  13. Unload 函数:将最优解传递给原始指针。
  14. registerconstraint 函数:注册约束条件及其对应的误差计算函数。
  15. registerdependency 函数:注册约束条件及其依赖项。
  16. GetInitialValue 函数:获取参数的初始值。
  17. GetVectorSize 函数:获取参数向量的大小。

这些函数共同用于加载约束条件、计算误差、计算梯度以及求解最优解

23

24

25

这篇关于macad.managed解析interop,occextentions,occhelper的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/883329

相关文章

解析 XML 和 INI

XML 1.TinyXML库 TinyXML是一个C++的XML解析库  使用介绍: https://www.cnblogs.com/mythou/archive/2011/11/27/2265169.html    使用的时候,只要把 tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

陀螺仪LSM6DSV16X与AI集成(8)----MotionFX库解析空间坐标

陀螺仪LSM6DSV16X与AI集成.8--MotionFX库解析空间坐标 概述视频教学样品申请源码下载开启CRC串口设置开启X-CUBE-MEMS1设置加速度和角速度量程速率选择设置FIFO速率设置FIFO时间戳批处理速率配置过滤链初始化定义MotionFX文件卡尔曼滤波算法主程序执行流程lsm6dsv16x_motion_fx_determin欧拉角简介演示 概述 本文将探讨

【文末附gpt升级秘笈】腾讯元宝AI搜索解析能力升级:千万字超长文处理的新里程碑

腾讯元宝AI搜索解析能力升级:千万字超长文处理的新里程碑 一、引言 随着人工智能技术的飞速发展,自然语言处理(NLP)和机器学习(ML)在各行各业的应用日益广泛。其中,AI搜索解析能力作为信息检索和知识抽取的核心技术,受到了广泛的关注和研究。腾讯作为互联网行业的领军企业,其在AI领域的探索和创新一直走在前列。近日,腾讯旗下的AI大模型应用——腾讯元宝,迎来了1.1.7版本的升级,新版本在AI搜

消息认证码解析

1. 什么是消息认证码         消息认证码(Message Authentication Code)是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为MAC。         消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为MAC值。         根据任意长度的消息输出固定长度的数据,这一点和单向散列函数很类似

问题1,PE文件转到内存中出现解析PE不正确的问题

1,使用fopen(FileName, “r”) r的方式读取文件到内存,此时就可能存在问题了,r以只读方式,有时候不表示字符的有可能就不读了,那么内存中就不会是完整的原始文件。所以此时要采用rb,二进制读取的方式。 bool ReadFileToMem(char* FileName, char**buf) { FILE* f; f = fopen(FileName, “rb”); if

[大师C语言(第三十六篇)]C语言信号处理:深入解析与实战

引言 在计算机科学中,信号是一种软件中断,它允许进程之间或进程与内核之间进行通信。信号处理是操作系统中的一个重要概念,它允许程序对各种事件做出响应,例如用户中断、硬件异常和系统调用。C语言作为一门接近硬件的编程语言,提供了强大的信号处理能力。本文将深入探讨C语言信号处理的技术和方法,帮助读者掌握C语言处理信号的高级技巧。 第一部分:C语言信号处理基础 1.1 信号的概念 在Unix-lik

免费内网穿透工具 ,快解析内网穿透解决方案

在IPv4公网IP严重不足的环境下,内网穿透技术越来越多的被人们所使用,使用内网穿透技术的好处有很多。 1:无需公网ip 物以稀为贵,由于可用的公网IP地址越来越少,价格也是水涨船高,一个固定公网IP一年的成本要上万,而使用内网穿透技术则不需要公网IP的支持。 2:提高安全性 使用内网穿透技术,无需在路由器映射端口,我们知道黑客通常会使用端口扫描来寻找攻击对象,不映射端口能大大提高服务器的安全

混合密码系统解析

1. 概述         混合密码系统(hybrid cryptosystem)是将对称密码和非对称密码的优势相结合的方法。一般情况下,将两种不同的方式相结合的做法就称为混合(hybrid)。用混合动力汽车来类比的话,就相当于是一种将发动机(对称密码)和电动机(非对称密码)相结合的系统。         混合密码系统中会先用快速的对称密码来对消息进行加密,这样消息就被转换为了密文从而也就保证

带你解析Dagger2

1. Dagger2简介: Dagger2是Dagger1的分支,由谷歌公司接手开发,目前的版本是2.0。Dagger2是受到AutoValue项目的启发。 刚开始,Dagger2解决问题的基本思想是:利用生成和写的代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。 Dagger2具有以下好处: 1) 依赖的注入和配置独立于组件之外,注入的对象在一个独立、不耦合的地方初始化,这样在改