Hi
I have example where the brep which is produced with RhinoCutupSurface is invalid if RhinoCutupSurface is called from second thread. If I call IsValid on the result brep from the second thread it returns true so I aspect the brep to be valid. Then after the second thread ends, I am trying to add the result brep to the rhino document from the main thread , but adding the brep to the document fails, i.e I am getting message box which says : " CRhinoDoc::AddBrepObject - brep.IsValid is false. Brep not added".
If RhinoCutupSurface is called from the main thread with the same input, then the brep is valid and it is successfully added to the rhino document.
So , does this means that RhinoCutupSurface has some issues when called from second thread, cause my understading is that this is allowable to generate geometry on second thread as long as uou do not touch the rhino document.
To test the code example use the 3dm file in the following link 3dm fileand then select the surface and the curve when prompted.
Here is the test code :
class CCommandTestRhinoCutUpSurface : public CRhinoCommand
{
public:
CCommandTestRhinoCutUpSurface() {}
~CCommandTestRhinoCutUpSurface() {}
UUID CommandUUID()
{
// {CE2524D1-4B11-44CF-971C-5135CF322F71}
static const GUID TestRhinoCutUpSurfaceCommand_UUID =
{ 0xCE2524D1, 0x4B11, 0x44CF, { 0x97, 0x1C, 0x51, 0x35, 0xCF, 0x32, 0x2F, 0x71 } };
return TestRhinoCutUpSurfaceCommand_UUID;
}
const wchar_t* EnglishCommandName() { return L"TestRhinoCutUpSurface"; }
const wchar_t* LocalCommandName() { return L"TestRhinoCutUpSurface"; }
CRhinoCommand::result RunCommand( const CRhinoCommandContext& );
};
// The one and only CCommandTestRhinoCutUpBrep object
static class CCommandTestRhinoCutUpSurface theTestRhinoCutUpSurfaceCommand;
struct DataForThread
{
const ON_Surface* srf;
ON_SimpleArray<ON_Curve*> crvs;
ON_Brep* resultBrep;
};
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
DataForThread * data = ((DataForThread*)lpParam);
ON_SimpleArray<ON_Brep*> brepArray;
RhinoCutUpSurface(*data->srf, true, data->crvs, 0.01, 0.02, brepArray);
if(brepArray.Count()!=0)
{
ON_Brep* theFirstBrep=brepArray[0];
// here it says is valid
bool isValid = theFirstBrep->IsValid();
data->resultBrep = theFirstBrep->Duplicate();
}
return 0;
}
DataForThread g_data;
CRhinoCommand::result CCommandTestRhinoCutUpSurface::RunCommand( const CRhinoCommandContext& context )
{
//select surface
CRhinoGetObject gs1;
gs1.SetCommandPrompt(L"Select the surface" );
gs1.SetGeometryFilter( CRhinoGetObject::surface_object );
gs1.GetObjects( 1, 1 );
if( gs1.CommandResult() != CRhinoCommand::success )
return gs1.CommandResult();
const ON_Surface* srf = gs1.Object(0).Surface();
g_data.srf = srf;
// select curve
CRhinoGetObject go;
go.SetCommandPrompt( L"Select curve" );
go.SetGeometryFilter( CRhinoGetObject::curve_object );
go.GetObjects( 1, 1 );
if( go.CommandResult() != success )
return go.CommandResult();
const CRhinoObjRef& obj_ref = go.Object(0);
const ON_Curve* crv = obj_ref.Curve();
ON_SimpleArray<ON_Curve*> arrayCurvs;
arrayCurvs.Append(crv->DuplicateCurve());
g_data.crvs = arrayCurvs;
// NO problem when the brep is generated fro mthe main thread
ON_SimpleArray<ON_Brep*> brepArray;
RhinoCutUpSurface(*srf, true, arrayCurvs, 0.01, 0.02, brepArray);
if(brepArray.Count()==0)
return CRhinoCommand::failure;
ON_Brep* theFirstBrep=brepArray[0];
bool isValid = theFirstBrep->IsValid();
RhinoApp().ActiveDoc()->AddBrepObject(*theFirstBrep);
RhinoApp().ActiveDoc()->Redraw();
// Create thread , and generate brep with RhinoCutUpSurface in second thread
HANDLE handleThread = CreateThread( NULL, 0,
ThreadFunc, &g_data, 0, NULL);
WaitForSingleObject(handleThread, INFINITE);
// try to add the brep to document that was generated in second thread
// here it says is invalid and AddBrepObject fails
bool isValidThreadBrep = g_data.resultBrep->IsValid();
RhinoApp().ActiveDoc()->AddBrepObject(*g_data.resultBrep);
RhinoApp().ActiveDoc()->Redraw();
return CRhinoCommand::success;
}