[Closed] C++ Dividing Segments from Splines
Hi, I am trying to Divide segments of a spline. I know there is the DoSegDivide, but it only seems to work if a segment is selected. I need to be able to divide a whole spline by different number of divisions depending on the segment, and without selecting each segment each time I want to divide. Any ideas on what to do ??
what’s wrong with selecting? selecting is just a setting one of the flags.
Wouldn’t going into the sublevel object and selecting each segment over and over make it slow ?? Also I couldn’t find anything on selecting certain segments by index apart from SetSegmentSel within SplineShape, which I couldn’t get to work Am I just missing something really simple ??
Wouldn’t going into the sublevel object and selecting each segment over and over make it slow ??
“going into sublevel object” is a edit modifier thing, the base objects have selection sets (usually bit arrays) that they operate on. So most methods look to see if the selection bit for whatever is set and if it is do the operation… the only net out come is if you leave the bits set to selected when you’ve finish the operation the selection will be display on screen when in that subject mode of an “edit modifier”
Ahh ok, that makes a lot of sense, thank you. After testing it, I didn’t need to be in the subobject to get it to divide. Although, the DoSegDivide from SplineShape needs to be on the Modify Mode to do the dividing. Is there a way around this, or a different way ?? Many thanks guys.
ip = GetCOREInterface();
t = GetCOREInterface()->GetTime();
for (int i=0; i < ip->GetSelNodeCount(); i++){
INode *node = ip->GetSelNode(i);
SetUserProp(node);
BOOL isReversed = FALSE;
Object *newObject = node->GetObjectRef();
if(newObject->SuperClassID() == SHAPE_CLASS_ID){
if(newObject->ClassID() != Class_ID(SPLINESHAPE_CLASS_ID, 0)){
SplineShape* newSpline = (SplineShape*)newObject->ConvertToType(t, Class_ID(SPLINESHAPE_CLASS_ID, 0));
newObject = newSpline->CollapseObject();
node->SetObjectRef(newObject);
newObject = node->GetObjectRef();
}
SplineShape* newSpline = (SplineShape*) newObject;
BezierShape* bs = &((SplineShape*)newObject)->shape;
ExecuteMAXScriptScript(_T("max modify mode"), 0, 0);
bs->segSel[0].Set(2, 1);
newSpline->DoSegDivide(4);
bs->segSel[0].ClearAll();
bs->InvalidateGeomCache();
bs->UpdateSels();
ip->RedrawViews(ip->GetTime());
}
}
I’m just doing 1 segment at the moment for testing purposes.
did you look into editspl.cpp? DivideSegment doesn’t need modifier panel opened.
I did have a look, but didn’t quite understand how it was doing the dividing.
my starting point for subdividing a spline would be nspline.cpp from the mods sample in the sdk
void NormalizeSpline::BuildSkin(TimeValue t,ModContext &mc, ObjectState * os) {
SplineShape *shape = (SplineShape *)os->obj->ConvertToType(t,splineShapeClassID);
int polys = shape->shape.splineCount;
int poly;
float cinc = 0.0f;
float TotalLength = 0.0f;
for(poly = 0; poly < polys; ++poly)
{
shape->shape.splines[poly]->ComputeBezPoints();
TotalLength += shape->shape.splines[poly]->SplineLength();
}
cinc = nlength/TotalLength;
cinc = cinc/10.0f;
if (cinc>0.001f) cinc = 0.001f;
for(poly = 0; poly < polys; ++poly)
{
//get spline
//get number segs
//get points
float SegLength;
SegLength = nlength*nlength;
float inc = 0.001f;
float CurrentPercent = 0.0f;
inc = cinc;
Point3 CurrentPoint,NextPoint;
Tab<Point3> PointList;
PointList.ZeroCount();
while (CurrentPercent < 1.0)
{
CurrentPoint = shape->shape.splines[poly]->InterpCurve3D(CurrentPercent);
PointList.Append(1,&CurrentPoint,1);
NextPoint = CurrentPoint;
while ((LengthSquared(CurrentPoint-NextPoint)<SegLength) && (CurrentPercent <1.0f))
{
CurrentPercent += inc;
NextPoint = shape->shape.splines[poly]->InterpCurve3D(CurrentPercent);
}
}
int i,closed;
closed = shape->shape.splines[poly]->Closed();
if (!shape->shape.splines[poly]->Closed())
{
NextPoint = shape->shape.splines[poly]->GetKnotPoint(shape->shape.splines[poly]->KnotCount()-1);
PointList.Append(1,&NextPoint,1);
}
shape->shape.splines[poly]->NewSpline();
//add new points
if (closed)
shape->shape.splines[poly]->SetClosed();
else shape->shape.splines[poly]->SetOpen();
for (i=0;i<PointList.Count();i++)
{
shape->shape.splines[poly]->AddKnot(SplineKnot(KTYPE_AUTO,LTYPE_CURVE,
PointList[i],PointList[i],PointList[i]));
}
if (shape->shape.splines[poly]->KnotCount() == 1)
shape->shape.splines[poly]->AddKnot(SplineKnot(KTYPE_AUTO,LTYPE_CURVE,
PointList[PointList.Count()-1],PointList[PointList.Count()-1],PointList[PointList.Count()-1]));
shape->shape.splines[poly]->ComputeBezPoints();
for (i=0;i<shape->shape.splines[poly]->KnotCount();i++)
shape->shape.splines[poly]->SetKnotType(i,KTYPE_AUTO);
shape->shape.splines[poly]->ComputeBezPoints();
}
shape->shape.UpdateSels(); // Make sure it readies the selection set info
shape->shape.InvalidateGeomCache();
}
Right, I think I’m starting to understand this a bit more now. Thank you for all your help guys.