Notifications
Clear all

[Closed] nOOb question about moving vertices

Hi!

I come back in the wonderful worl of Max Development!

I have just a very simple question



 maxOps.CloneNodes $ cloneType:#reference   offset:[100, 0, 0] newNodes:&ObjectRef 
   	  select ObjectRef[1] 
   	   
   	
   	  addModifier $ (Edit_Poly()) 
   
   ... 
   
      max modify mode		  
      subobjectLevel = 1 
   	
      for i = 1 to num_vert01 do 
      ( 
   	  $.modifiers[#Edit_Poly].setSelection #Vertex #{} 
   	  $.modifiers[#Edit_Poly].Select #Vertex #{i} 
   	  $.modifiers[#Edit_Poly].SetOperation #Transform 
   	  $.modifiers[#Edit_Poly].MoveSelection    [(random -1 1),(random -1 1), (random -1 1)] 
   	  $.modifiers[#Edit_Poly].Commit () 
      ) 


Everything works fine, vertices are moved correctly. But, I had to change max mode to modify and I would like to avoid this.
Is there a direct way to move vertices on Edit_Poly modifier? (I try some other stuff but the original object was modified the same way as the reference…)

Here is the stuff I tried :

  polyop.setvert $ verts VertPos

Thanks for your help
François

4 Replies
 JHN

There’s no way around switching to modpanel, but you can maybe try the “with redraw off” context to do your actions in the modpanel and switch back when finished after your actions are finished. Look it up in the help file, it can seriously speed code up.

-Johan

Hi Francois,
as far as I know there is no way to access Edit Poly Modifier without having the command Panel open, in Modify mode and with EditPolyModifier as the currently active point in the Stack.

Here is the function I have got in my PolyWrapper structure to handle moveVerts for Editable Poly objects and Edit Poly Modifiers. Maybe it can help.

Before switching the Command Panel to Modify mode, you can store its status and restore it at the end of the move function.

/*
moveVerts <BitArray>vertsToMove <Point3 Array>shiftForEachVert <node>theNode <EditablePoly or EditPolyMod>theEditObj <bool>transformsInLocalSpace
*/

function moveVerts baVerts ap3Shift theNode theEditObj localSpace:true =
(
    if ((classOf theEditObj) == Editable_Poly) then
    (
        if (localSpace) then
        (
            polyOp.moveVert theEditObj baVerts ap3Shift
        )
        else
        (
            polyOp.moveVert theEditObj baVerts ap3Shift node:theNode
        )
    )
    else if ((classOf theEditObj) == Edit_Poly) then
    (
        if (getCommandPanelTaskMode() != #modify) do
            setCommandPanelTaskMode #modify

        if (modPanel.getCurrentObject() != theEditObj) do
            modPanel.setCurrentObject theEditObj

        if (localSpace) do
        (
            local localRM = theNode.transform.rotationPart as Matrix3
            ap3Shift = for p3Shift in ap3Shift collect (p3Shift * localRM)
        )

        local aiVerts = baVerts as Array

        with redraw off
        (
            local nRefCoordSys = getRefCoordSys()

            local nSubSelLevel = theEditObj.getEPolySelLevel()
            theEditObj.setEPolySelLevel #Vertex

            local baVertSelection = theEditObj.getSelection #Vertex node:theNode
            baVertSelection.count = theEditObj.getNumVertices()

            local baSelVerts = #{aiVerts[1]}
            baSelVerts.count = theEditObj.getNumVertices()

            theEditObj.setSelection #Vertex baSelVerts node:theNode

            setRefCoordSys #hybrid -- Needed, transformations are CoordSys sensitive 

            theEditObj.moveSelection [0,0,0] -- Hack needed to make all verts move
            theEditObj.commit()

            for i = 1 to aiVerts.count do
            (
                baSelVerts[aiVerts[i]] = true
                theEditObj.setSelection #Vertex baSelVerts node:theNode

                theEditObj.moveSelection ap3Shift[i] -- WorldSpace Required
                theEditObj.commit()

                baSelVerts[aiVerts[i]] = false
            )

            theEditObj.setSelection #Vertex baVertSelection node:theNode

            theEditObj.setEPolySelLevel nSubSelLevel

            setRefCoordSys nRefCoordSys
        )
    )
)
  • Enrico

Thanks a lot JHN and SyncViewS for your quick answer
I just tried the With Redraw off command. Unfortunatelly, it didn’t speed up so much the process. I think I will need to go onto the SDK to really speed up the process.

If you have any idea how to do it C++ wise, your help will also be very appreciated

Once again thanks a lot!

SyncViewS : your piece of code is really full of information that I will use to modifiy a littl bit mine to be more bullet proof!

Hi Francois,
I’m glad it helped. Here is the code of a similar function I’ve got in a PolyWrapper class in C++. But I need to warn you: while I’m quite fluent with MaxScript and previous function has been tested quite a lot, following code is just a hint. You should implement guards to avoid falling in run-time or out-of-range errors.

It is good if you plan to make the function integrated into some other code you got to achieve your goal. But if you’re looking for a way to build a function you can call from MaxScript, the structure is a little different. Take a look at “Writing MAXScript Plug-ins” in the SDK help, and the “mxsagni” sample, filed under: …\maxsdk\samples\maxscript\mxsagni. In particular to “polyop.cpp”. Last but not least: good luck!

/* where:

BaseObject* baseObj = GetCOREInterface()->GetCurEditObject(); // where the current edit object in the stack is and Editable Poly Object or an Edit Poly Modifier.

const Class_ID EPOLYMOD_CLASS_ID(0x79aa6e1d, 0x71a075b7); // barely documented!

if (baseObj->ClassID() == EPOLYOBJ_CLASS_ID)
{
    iep = GetEPolyInterface(baseObj->GetInterface(EPOLY_INTERFACE));
    obj = static_cast<Object*>(baseObj);
}
else if (baseObj->ClassID() == EPOLYMOD_CLASS_ID)
{
    iepm = GetEPolyModInterface(baseObj->GetInterface(EPOLY_MOD_INTERFACE));
    obj = getEPModObj();
}
*/

bool moveVert(BitArray verts, Point3* shift, bool local)
{
    if (baseObj->ClassID() == EPOLYOBJ_CLASS_ID)
    {
        if (local)
        {
            int j = 0;
            for (int i = 0; i < verts.GetSize(); ++i)
            {
                if (verts[i] == TRUE)
                {
                    obj->SetPoint(i, (obj->GetPoint(i) + shift[j++]));
                }
            }
        }
        else
        {
            Matrix3 nodeTM = node->GetNodeTM(GetCOREInterface()->GetTime());
            nodeTM.Invert();

            int j = 0;
            for (int i = 0; i < verts.GetSize(); ++i)
            {
                if (verts[i] == TRUE)
                {
                    obj->SetPoint(i, (obj->GetPoint(i) + nodeTM.VectorTransform(shift[j++]))); // world to local
                }
            }
        }

        iep->LocalDataChanged(GEOM_CHANNEL);

        return true;
    }
    else if (baseObj->ClassID() == EPOLYMOD_CLASS_ID)
    {
        BitArray index(verts.GetSize());

        if (local)
        {
            Matrix3 nodeTM = iepm->EpModGetNodeTM(GetCOREInterface()->GetTime());

            int j = 0;
            for (int i = 0; i < verts.GetSize(); ++i)
            {
                if (verts[i] == TRUE)
                {
                    index.ClearAll();
                    index.Set(i, TRUE);

                    iepm->EPMeshSetVert(index, (iepm->EpMeshGetVertex(i) + nodeTM.VectorTransform(shift[j++]))); // local to world
                }
            }
        }
        else
        {
            int j = 0;
            for (int i = 0; i < verts.GetSize(); ++i)
            {
                if (verts[i] == TRUE)
                {
                    index.ClearAll();
                    index.Set(i, TRUE);

                    iepm->EPMeshSetVert(index, (iepm->EpMeshGetVertex(i) + shift[j++]));
                }
            }    
        }

        iepm->EpModLocalDataChanged(GEOM_CHANNEL);

        return true;
    }
    return false;
}

This little piece of code cost me a lot of perspiration, enjoy!

  • Enrico