C++ custom tool SDK programming tip
Re: C++ custom tool SDK programming tip
I'm wondering if it wasn't be simpler to just subdivide components with custom catmull clark algorithm.
Because right now:
-getting new vertex pos is easy cause index doesn't change with subdees
-no way to get new edges out of non-subd edge?
-getting new polygons very slow
?
Because right now:
-getting new vertex pos is easy cause index doesn't change with subdees
-no way to get new edges out of non-subd edge?
-getting new polygons very slow
?
Re: C++ custom tool SDK programming tip
I've managed to greatly speed up face index searching by using binary search. So it's like 100 ms for 300k sphere (subdivided to 2million polys). But it still lags compared to tweak tool :<
Ray do you know is there any way to profile a plugin? Now im using clock() but I would have to decorate all code with clock() to know where plugin slowdowns.
For the record because doc is a bit lame in this matter (maybe its bug?):
GetPolygonTriangleIndex (LONG in_tindex, LONG &out_pindex) - will give us index of the polygon that was used to generate the triangle (original polygon from level 0)
GetPolygonTriangleIndices (CLongArray &out_array) - will give us indices of the polygons that was used to generate the triangles (NOT indices of original polygons from level 0, but from current level!!! )
Ray do you know is there any way to profile a plugin? Now im using clock() but I would have to decorate all code with clock() to know where plugin slowdowns.
For the record because doc is a bit lame in this matter (maybe its bug?):
GetPolygonTriangleIndex (LONG in_tindex, LONG &out_pindex) - will give us index of the polygon that was used to generate the triangle (original polygon from level 0)
GetPolygonTriangleIndices (CLongArray &out_array) - will give us indices of the polygons that was used to generate the triangles (NOT indices of original polygons from level 0, but from current level!!! )
Re: C++ custom tool SDK programming tip
No, don't know of any profiling tricks, what I ususally do is replace a block of code that I suspect being slow with something that delivers a fast but fake result, and see if it becomes faster.
Should work fine for custom tools because the dll always gets unloaded when the tool is not in action - Which is very nice because you can go from changed code to testing in Softimage literally in a few seconds.
There's probably something wrong with the the IndexArray getter --- it should get the generating polys not the result polys. Either that or the GetPolygonTriangleIndexArray function is missing
Should work fine for custom tools because the dll always gets unloaded when the tool is not in action - Which is very nice because you can go from changed code to testing in Softimage literally in a few seconds.
There's probably something wrong with the the IndexArray getter --- it should get the generating polys not the result polys. Either that or the GetPolygonTriangleIndexArray function is missing
softimage resources section updated Jan 5th 2024
Re: C++ custom tool SDK programming tip
hey piotrek
i am making a brush based custom tool myself (similar to 'meshPaint') and was wondering about your speed of access to the components of a mesh. i want to recreate exactly what the weight paint tool is doing with regards to orienting the brush with the surface. currently on activating the tool i am taking the selection and caching the normals. then during my MouseMove i access the component indices from a PickBuffer and use those indices to look up the normal(s) to use for alignment of my brush. the speed is acceptable currently but the lag of caching the normals might become a hindrance in the future.
i was wondering, if you dont mind sharing, your technique for accessing the normals of a selected mesh inside a custom tool. since these are custom interactive tools, of course speed is paramount.
thanks
steven
i am making a brush based custom tool myself (similar to 'meshPaint') and was wondering about your speed of access to the components of a mesh. i want to recreate exactly what the weight paint tool is doing with regards to orienting the brush with the surface. currently on activating the tool i am taking the selection and caching the normals. then during my MouseMove i access the component indices from a PickBuffer and use those indices to look up the normal(s) to use for alignment of my brush. the speed is acceptable currently but the lag of caching the normals might become a hindrance in the future.
i was wondering, if you dont mind sharing, your technique for accessing the normals of a selected mesh inside a custom tool. since these are custom interactive tools, of course speed is paramount.
thanks
steven
Re: C++ custom tool SDK programming tip
Hi,
I calculate them by myself, edge& point data from polymeshes were always giving me weird results
I calculate them by myself, edge& point data from polymeshes were always giving me weird results
Code: Select all
CVector3 getEdgeNormal(ToolContext& in_ctxt,Edge &in_edge,bool in_mulmatrix)
{
CPolygonFaceRefArray l_ep(in_edge.GetNeighborPolygons());
int cnt = l_ep.GetCount();
CVector3 vn;
for (int i=0;i<cnt;i++)
{
PolygonFace face(l_ep[i]);
CVector3 s,e,n;
n=getPolyNormal(in_ctxt,face,false);
n.NormalizeInPlace();
vn+=n;
}
X3DObject in_obj=in_edge.GetParent();
if(in_mulmatrix)
vn*=in_obj.GetKinematics().GetGlobal().GetTransform().GetRotationMatrix3();
vn.NormalizeInPlace();
return vn;
}
CVector3 getVertexNormal(ToolContext& in_ctxt,Vertex &in_v, bool in_mulmatrix) //returns normal
{
CPolygonFaceRefArray l_vp(in_v.GetNeighborPolygons());
int cnt = l_vp.GetCount();
CVector3 vn;
for (int i=0;i<cnt;i++)
{
PolygonFace face(l_vp[i]);
CVector3 s,e,n;
n=getPolyNormal(in_ctxt, face,false);
vn+=n;
}
X3DObject in_obj=in_v.GetParent();
if(in_mulmatrix)
vn*=in_obj.GetKinematics().GetGlobal().GetTransform().GetRotationMatrix3();
vn.NormalizeInPlace();
return vn;
}
// calculate polygon normal (Newell's method) http://www.opengl.org/wiki/Calculating_a_Surface_Normal
CVector3 getPolyNormal(ToolContext& in_ctxt, PolygonFace &in_poly, bool in_mulmatrix)
{
X3DObject in_obj = in_poly.GetParent();
PolygonMesh mesh( in_obj.GetActivePrimitive().GetGeometry() );
CVertexRefArray verts( in_poly.GetVertices());
CLongArray tri_ind( in_poly.GetTriangleSubIndexArray());
CVector3Array n,p;
UINT vertCnt = verts.GetCount();
double x=0,y=0,z=0;
for(UINT i=0;i<vertCnt;i++)
{
Vertex current = verts[i];
Vertex next = verts[ (i+1) % vertCnt];
CVector3 c(current.GetPosition() );
CVector3 n(next.GetPosition() );
x= x+ ( (c[1]-n[1])* (c[2]+n[2]) );
y= y+ ( (c[2]-n[2])* (c[0]+n[0]) );
z= z+ ( (c[0]-n[0])* (c[1]+n[1]) );
}
CVector3 normal(x,y,z);
if( in_mulmatrix )
normal *= in_obj.GetKinematics().GetGlobal().GetTransform().GetRotationMatrix3();
normal.NormalizeInPlace();
return normal;
}
Re: C++ custom tool SDK programming tip
thanks for the code snip.. i see for the polygon normal function you have a PolygonFace argument. where is this coming from? is the PickBuffer giving you this class? i thought the PickBuffer just gets you the Index of the filter you choose and not the actual CRef which you can cast to a PolygonFace?
s
s
Re: C++ custom tool SDK programming tip
Hi Steven.
It might not be the better way to do it, but for my LivePaint Tool, I'm caching the geometry in the Activate callback:
oSel = selected[0];
oGeo= oSel.GetActivePrimitive().GetGeometry();
oGeo.SetupPointLocatorQueries(siClosestSurfaceRaycastIntersection, & oSel.GetKinematics().GetGlobal().GetTransform(),-1,NULL,1);
then on move:
PointLocatorData brushCenterLocator = oGeo.GetRaycastIntersections( 1, (double*)&l_cursorRay.GetOrigin(), (double*)&oDir, siSegmentIntersection );;
oGeo.EvaluatePositions(brushCenterLocator, -1, 0, pos);
oGeo.EvaluateNormals(brushCenterLocator, siInterpolatedVertexAngleBasedGeometricNormals, -1, 0, lNorm);
norm.Set(lNorm[0],lNorm[1],lNorm[2]);
brushCenter.Set(pos[0],pos[1],pos[2]);
Cheers
It might not be the better way to do it, but for my LivePaint Tool, I'm caching the geometry in the Activate callback:
oSel = selected[0];
oGeo= oSel.GetActivePrimitive().GetGeometry();
oGeo.SetupPointLocatorQueries(siClosestSurfaceRaycastIntersection, & oSel.GetKinematics().GetGlobal().GetTransform(),-1,NULL,1);
then on move:
PointLocatorData brushCenterLocator = oGeo.GetRaycastIntersections( 1, (double*)&l_cursorRay.GetOrigin(), (double*)&oDir, siSegmentIntersection );;
oGeo.EvaluatePositions(brushCenterLocator, -1, 0, pos);
oGeo.EvaluateNormals(brushCenterLocator, siInterpolatedVertexAngleBasedGeometricNormals, -1, 0, lNorm);
norm.Set(lNorm[0],lNorm[1],lNorm[2]);
brushCenter.Set(pos[0],pos[1],pos[2]);
Cheers
Re: C++ custom tool SDK programming tip
This way, with Pick method (in_objects should be narrowed down to selection/or object under cursor for faster picking)
or
I think it's all necessary code...afaik pickbuffer is faster, and you can cache it (like whole screen, but it takes time so there is a microlag with many objects in view)
Code: Select all
X3DObject GetPolyComponent(ToolContext& in_ctxt,CRef &target, PolygonFace &out_polyface)
{
X3DObject l_meshObject;
CComAPIHandler cCollItem(target);
CComAPIHandler cSubComp(cCollItem.GetProperty(L"SubComponent"));
CComAPIHandler cCompColl(cSubComp.GetProperty(L"ComponentCollection"));
CValueArray indices = cSubComp.GetProperty( L"ElementArray" );
l_meshObject = cSubComp.GetProperty( L"Parent3DObject" );
PolygonMesh pmesh( l_meshObject.GetActivePrimitive().GetGeometry() );
CString l_subcomp = cSubComp.GetProperty(L"Type");
if(LONG(indices.GetCount() ) == 1L)
if ( l_subcomp == L"polySubComponent" ) {
out_polyface = pmesh.GetPolygons().GetItem((LONG)indices[0]);
m_pickedSubcompType = kPoly;
}
return l_meshObject;
}
CStatus GetGeometrySubcomponentData(ToolContext& in_ctxt, LONG x, LONG y, CRefArray& in_objects, X3DObject& out_pickedObject, PolygonFace& out_pickedPolyFace, CVector3& out_pickedNormal)
{
CLongArray l_points;
l_points.Add(x);
l_points.Add(y);
CRefArray components;
X3DObject l_picked = in_objects[0];
//only polys
in_ctxt.Pick( l_points, siPickSingleSubComponent, siPickRaycast, siPolygonFilter, in_objects, components );
if( components.GetCount() != 0 )
{
out_pickedObject = GetPolyComponent(in_ctxt,components[0], out_pickedPolyFace);
out_pickedNormal = getPolyNormal(in_ctxt,out_pickedPolyFace, false);
}
else
return CStatus::False;
return CStatus::OK;
}
Code: Select all
CRefArray l_objects;
PickBuffer l_pickbuff = in_ctxt.GetPickBuffer(x,y,4,4, siObjectFilter, l_objects);
CRef l_picked = l_pickbuff.GetObjectAtPosition(x, y );
if ( !l_picked.IsValid() )
return CStatus::False;
PolygonMesh mmesh = l_picked.GetActivePrimitive().GetGeometry();
CRefArray l_cobjects;
l_cobjects.Add(l_picked);
PickBuffer l_pickbuffComp = in_ctxt.GetPickBuffer(x,y,4,4, siPolygonFilter, l_cobjects);
LONG pti = l_pickbuffComp.GetComponentIndexAtPosition(x, y);
if (pti == -1) {
#ifdef _DEBUG
logmsg(" l_pickbuffComp.GetComponentIndexAtPosition(x, y); FAIL");
#endif
return CStatus::False;
}
PolygonFace pface = mmesh.GetPolygons().GetItem(pti);
Re: C++ custom tool SDK programming tip
Hey Ahmidou, I think SetupPointLocatorQueries is very slow when you pass -1 (all polys) argument, so its better to restrict search for particular polygons
Re: C++ custom tool SDK programming tip
@piotrek, yes caching normals in the view frustrum seems to be what softimage weight paint brush does. if you give it a try with >500k triangles you will see initial lag and various lags happen after camera manipulation.
i am going to stick with the PickBuffer and use what i have learned from this thread to do some performance tests. use a PickBuffer the size of the view and cache it, then use either Pick or PickBuffer to get components during MouseMove and orient the brush. the PickBuffer will allow me to query many components if i want to do averaging of normals based brush radius. not sure if this is desired...
btw, i am trying to build my brush to be as generic and basic as possible, i will open source it and provide others with a starting point. once i have something decent to share we can start implementing different techniques for the best performance. hopefully you fine fellows can find some time to contribute back to the project.
thanks guys!
steven
i am going to stick with the PickBuffer and use what i have learned from this thread to do some performance tests. use a PickBuffer the size of the view and cache it, then use either Pick or PickBuffer to get components during MouseMove and orient the brush. the PickBuffer will allow me to query many components if i want to do averaging of normals based brush radius. not sure if this is desired...
btw, i am trying to build my brush to be as generic and basic as possible, i will open source it and provide others with a starting point. once i have something decent to share we can start implementing different techniques for the best performance. hopefully you fine fellows can find some time to contribute back to the project.
thanks guys!
steven
Re: C++ custom tool SDK programming tip
Nice Steven! too bad I didn't found the time to finish mine... Anyway as piotrek pointed it was slow with dense meshes and your's should be more effective
Re: C++ custom tool SDK programming tip
Steven what about cmake tutorial you mentioned some time ago on mailinglist ;)
Re: C++ custom tool SDK programming tip
i made the first part a while ago, just not the second part which is needed for new projects using cmake. feel free to ask my any questions though... maybe i can turn this new project into a tutorial on cmake also
Last edited by scaron on 01 Aug 2012, 01:08, edited 1 time in total.
Re: C++ custom tool SDK programming tip
just wanted to note that you can talk to the developer of the tool SDK (and the tweak and manipulators), Brent, by posting on the XSI mailing list.
Re: C++ custom tool SDK programming tip
i figured brent is too busy working on maya ;) thanks for the reminder...
s
s
Re: C++ custom tool SDK programming tip
here is the code...
https://github.com/caron/SimpleBrush
this basic brush looks like the built in weight paint brush, adjusting the radius with the r key works, normal alignment is still wrong. i am trying to mimic the built in weight paint brush, i havent figured out how they're doing the smooth interpolation or averaging yet. you can see it on the default sphere when you move the brush across the surface.
i am sharing for others who haven't made a brush tool yet but want to, this should could be a nice start. piotrek wont find anything new in here ;)
steven
https://github.com/caron/SimpleBrush
this basic brush looks like the built in weight paint brush, adjusting the radius with the r key works, normal alignment is still wrong. i am trying to mimic the built in weight paint brush, i havent figured out how they're doing the smooth interpolation or averaging yet. you can see it on the default sphere when you move the brush across the surface.
i am sharing for others who haven't made a brush tool yet but want to, this should could be a nice start. piotrek wont find anything new in here ;)
steven
Who is online
Users browsing this forum: No registered users and 25 guests