Convert any shape to Editable Spline

Convert any shape to Editable Spline

Anonymous
適用対象外
2,779件の閲覧回数
16件の返信
メッセージ1/17

Convert any shape to Editable Spline

Anonymous
適用対象外

Hello,

 

I'm trying to convert a Shape object (Line for example) to an Editable Spline in C#.

 

Here's my code : 

 

public int ConvertToEditSpline(IINode node)
{
    if (node.ObjectRef.SuperClassID != SClass_ID.Shape) 
        return -1;

    if (node.ObjectRef.ClassID.PartA == (uint)BuiltInClassIDA.SPLINESHAPE_CLASS_ID)
        return 0;

    IObjectState objstate = node.ObjectRef.Eval(MaxInterfaces.Ip.Time);
    IShapeObject obj = objstate.Obj as IShapeObject;
    
    Console.WriteLine(obj.CanConvertToType(MaxUtils.SplineShapeClassID).ToString());
    // Print "1", so it can convert the object.

    ISplineShape newSpline = obj.ConvertToType(MaxInterfaces.Ip.Time, MaxUtils.SplineShapeClassID) as ISplineShape;
    // newSpline is null...

    if (newSpline == null)
        return -1;

    node.ObjectRef = newSpline.CollapseObject;
    return 0;
}

As you can, everytime I try to convert a ShapeObject to SplineShape, it returns null.

 

How can I solve this ?

 

Thank you.

0 件のいいね
2,780件の閲覧回数
16件の返信
返信 (16)
メッセージ2/17

Anonymous
適用対象外

No one ? @Swordslayer maybe ? 🙂

0 件のいいね
メッセージ3/17

Swordslayer
Advisor
Advisor

I'm not using C# in max actively, @danielgsantana might be a better choice. You might try something along the lines of

 

ISplineShape newSpline = global.SplineShape.Marshal(obj.NativePointer);

but judging by the unanswered I can't seem to get a cast working from IShapeObject to ISplineShape thread on cgtalk, it definitely doesn't look like an easy task.

0 件のいいね
メッセージ4/17

Anonymous
適用対象外

@Swordslayer I just tried it, the object seems to be non-null, i can access to Shape member, but the SplineCount is equal to 0 unfortunately.

 

Maybe my function is not correct : 

 

        public static ISplineShape GetSplineShapeFromINode(IINode node, int t, ref bool deleteIt)
        {
            deleteIt = false;
            IObject obj = node.ObjectRef.Eval(t).Obj;

            if (obj.SuperClassID == SClass_ID.Shape)
            {
                ISplineShape pSplineShape = MaxInterfaces.Global.SplineShape.Marshal(obj.ConvertToType(0, SplineShapeClassID).CollapseObject.NativePointer);
                if (obj != pSplineShape)
                    deleteIt = true;
                return pSplineShape;
            }
            return null;
        }

Could be nice also to get the SplineShape of an EditableSpline which uses Modifiers.

0 件のいいね
メッセージ5/17

danielgsantana
Contributor
Contributor

Michael, what version of 3dsmax are you using?

 

There a lot of dead ends in Autodesk.Max .NET depending on the version used. Some methods are pure virtual with no implementation, and others don't have the interface's implemented in .NET, making them useless.

 

Have you looked at the MaxPlusDotNet.dll, it's what is actively develop as a bridge to .NET, and serves for MCG backend and Python.

 

Cheers,

Daniel

Technical Director / Co-founder
You can do it! VFX - www.ycdivfx.com
Lisbon/ Porto - Portugal
0 件のいいね
メッセージ6/17

Anonymous
適用対象外

hi @danielgsantana, I am currently using Max 2016 SP4 (I need SP4 for some new features in the SDK).

 

I didn't use MaxPlusDotnet because I found it very limited, and since my plugin has something like 15k lines of codes, I don't want to change everything. Maybe I can bridge both assemblies using objects Handles but can't figure out for the moment...

 

 

0 件のいいね
メッセージ7/17

Alfred.DeFlaminis
Alumni
Alumni

Hello @Anonymous,


This is a bit above my ability to help with, but I'm going to move this thread to the Programming forum because I think there are a number of programmers that read that forum instead of general that may be able to help you.  My best recommendation here is that you post this on the ADN Forums to see if you can get programmer help with this issue.  I do realize that doesn't solve your problem but it's my best suggestion for this particular issue.  

 

Best Regards,

0 件のいいね
メッセージ8/17

denisT.MaxDoctor
Advisor
Advisor

@Alfred.DeFlaminis wrote:

I'm going to move this thread to the Programming forum because I think there are a number of programmers that read that forum instead of general that may be able to help you.  My best recommendation here is that you post this on the ADN Forums to see if you can get programmer help with this issue.  


does this link not work for me only?

0 件のいいね
メッセージ9/17

Swordslayer
Advisor
Advisor

@Anonymous wrote:

@Alfred.DeFlaminis wrote:

I'm going to move this thread to the Programming forum because I think there are a number of programmers that read that forum instead of general that may be able to help you.  My best recommendation here is that you post this on the ADN Forums to see if you can get programmer help with this issue.  


does this link not work for me only?


Well, I certainly can't get any further than either going back through the link to the Programming forum here, or membership choice (1400 €  or 2200 €). So you are not alone.

0 件のいいね
メッセージ10/17

denisT.MaxDoctor
Advisor
Advisor

i don't use c# for these things but a simplified c++ code might be as:

 

bool ConvertSplineShape(INode* node)
{
	ReferenceTarget* ref = node->GetObjectRef();
	if (ref && ((Object*)ref)->CanConvertToType(splineShapeClassID)) 
	{ 
		TimeValue t = GetCOREInterface()->GetTime();
		ObjectState os = node->EvalWorldState(t);
		Object* obj = (Object*)os.obj->ConvertToType(t, splineShapeClassID);

		node->SetObjectRef(obj);
		node->NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
		node->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);

		return true;
	}
	return false;
}

 

0 件のいいね
メッセージ11/17

Alfred.DeFlaminis
Alumni
Alumni

Hello @denisT.MaxDoctor and @Swordslayer,

 

That may be a mistake on my end if that link is broken.  It's weird because it works in Chrome for me but not IE.  I've updated it with a new link and my apologies for the problem there.

 

There is a free version of the ADN, so hopefully that can help @Swordslayer.   I don't see a Max specific API forum so the free version may not work for this issue, but the 3ds Max SDK Blog has a comments section where you may be able to get an answer if there is a related blog post.  I have links below:

 

ADN Base page

 

The 3ds Max SDK Blog 

 

Best Regards, 

0 件のいいね
メッセージ12/17

Swordslayer
Advisor
Advisor

@Alfred.DeFlaminis It's kind of confusing, when I click the first link or when I click the free ADN option from the second link, I always get this page which redirects back here when I click any of the forums (i.e. to subforums accessible directly from the main Autodesk forums page).

 

ADN.png

メッセージ13/17

danielgsantana
Contributor
Contributor
Here is a simple conversion of the Dennis code to C#, the notification
isn't right, since I need to go the headers in the SDK to see the right
values for the parts.

public bool ConvertSplineShape(INode node)
{
var objRef = node.ObjectRef;
if (objRef != null &&
objRef.CanConvertToType(GlobalInterface.Instance.SplineShapeClassID) != 0)
{
var t = GlobalInterface.Instance.COREInterface.Time;
var os = node.EvalWorldState(t, true);
var obj = os.Obj.ConvertToType(t,
GlobalInterface.Instance.SplineShapeClassID);
node.ObjectRef = obj;

node.NotifyDependents(GlobalInterface.Instance.Interval.Create(-1, -1),
(UIntPtr)0, RefMessage.SubanimStructureChanged, (SClass_ID)0xfffffff0,
true, null, NotifyDependentsOption.AllowOptimizations);

node.NotifyDependents(GlobalInterface.Instance.Interval.Create(-1, -1),
(UIntPtr)0, RefMessage.Change, (SClass_ID)0xfffffff0, true, null,
NotifyDependentsOption.AllowOptimizations);
return true;
}
return false;
}
Technical Director / Co-founder
You can do it! VFX - www.ycdivfx.com
Lisbon/ Porto - Portugal
メッセージ14/17

Swordslayer
Advisor
Advisor

You can use Autodesk.Max.MaxPlus.Constants, there is NotifyAll which works well when cast to SClass_ID. I've used it elsewhere but in the end had to find a non-C# way as the NotifyDependents call (or rather NotifyDependents_) worked in 2016 and errored in 2017 (might be just me not being good enough with C#, gave up at that point).

メッセージ15/17

Alfred.DeFlaminis
Alumni
Alumni

I see what you mean @Swordslayer.  I'm not much of a programmer so I haven't spent much time in there, but it does seem to be mostly blogs and a link to the programming forum.  I have the relevant blogs below, which I found by clicking Autodesk Platform Technologies on that page, then 3ds Max.  It does seem rather limited, so I may not suggest it in the future for such a specific topic.  

 

Blogs

 

Get news, expert tips and insider resources directly from Autodesk software engineers

3ds Max related blogs:

GetCoreInterface” (3ds Max SDK) – Kevin Vandecar

3D SDK and Scripting Mayhem” – Christopher Diggins blog that often refers to 3ds Max, but also considers many other technologies.

Max Station”: Learn Tips and tricks from the Autodesk product support team.

Louis Marcoux Tutorials”: A great series of tutorial style entries from a true expert, Louis Marcoux.

 

Best Regards,

0 件のいいね
メッセージ16/17

Alfred.DeFlaminis
Alumni
Alumni

Hello @Anonymous,

 

I'm a bit out of my depth in this thread but I wanted to check in to see if any of these suggestions helped with your issue.  If so, would you please mark any posts that helped with the solution, and thank you for doing so!

Best Regards,

0 件のいいね
メッセージ17/17

mmoraisdois
Participant
Participant

Works!!  

node.NotifyDependents(IntervalFOREVER, (UIntPtr)0, RefMessage.SubanimStructureChanged, (SClass_ID)Constants.NotifyAll, true, null,
     NotifyDependentsOption.AllowOptimizations);

 node.NotifyDependents(IntervalFOREVER, (UIntPtr)0, RefMessage.Change, (SClass_ID)Constants.NotifyAll, true, null,
     NotifyDependentsOption.AllowOptimizations);

 ip.RedrawViews(ip.Time, RedrawFlags.Normal, null);  // Redraw the views to reflect any changes made to the object  

Add   using Constants = Autodesk.Max.MaxPlus.Constants;    on top 
only works after adding the (SClass_ID)Constants.NotifyAll

Thanks to Swordslayer.

0 件のいいね