Draw a point in View,how to select it?



  • Hi,
    I registered an object plug-in with only Init() and Draw() functions. I draw a point in the view . How can I use the selection tool select this point and activate the object?

    Thanks for any help!



  • What is Initial()?

    A "point" drawn in a Draw() function is just that: a colored pixel in the viewport. There is nothing to select.

    I don't know what you want to do, but it seems that what you may want are handles. Such a handle can be selected and moved.

    You can handle handles by implementing GetHandleCount(), GetHandle(), SetHandle().

    The roundedtube.cpp example uses implements these functions.



  • @PluginStudent Thanks for you help.

    (initial() ->corrected -> Init() 😊)

    c++ ,i use DrawPointArray() to draw point,because i want to set custom color and point size.

    in my python plugin use DrawPoints() to draw point in view,when selection tool select point(draw in view),the
    plug_in Object can be selected.

    just like null object(display can be selected)



  • hello,

    one idea is maybe to use HUD. Like the character tool that got a button to draw some hud element.
    The problem is that i'm not sure if you can update them and move them to represent a point.
    But you can definitely click on them and launch a command ID

    This example will add a cube to the scene and create a HUD for it.

    When you click on the hud, it select the cube and activate the "move tool"

    
    #include "maxon/apibase.h"
    #include "c4d_basedocument.h"
    #include "lib_viewport.h"
    #include "lib_description.h"
    #include "modelingids.h"
    
    
    static maxon::Result<void> pc12312(BaseDocument* doc)
    {
    
    	if (doc == nullptr)
    		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION, "a valid document must be passed"_s);
    
    	// Creates the viewport HUD where we will add our controls
    	AutoAlloc<ViewportHUD> hud;
    	if (hud == nullptr)
    		return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "couldn't create the viewport HUD"_s);
    
    
    	// Add a cube to the scene
    	BaseObject* cube = BaseObject::Alloc(Ocube);
    	doc->InsertObject(cube, nullptr, nullptr);
    
    	// Retrieves the baseDraw of the active scene
    	BaseDraw* bd = doc->GetActiveBaseDraw();
    	if (bd == nullptr)
    		return maxon::NullptrError(MAXON_SOURCE_LOCATION, "cannot retrieve the basedraw of the active document"_s);
    	
    	// start an undo so the hud can be undone 
    	if (doc->StartUndo())
    	{
    		// Retrieves the scenehook just to add undo step in the stack
    		BaseSceneHook* hudhook = doc->FindSceneHook(ID_VIEW_SCENEHOOKHUD);
    		if (hudhook)
    		{
    
    			doc->AddUndo(UNDOTYPE::CHANGE_SMALL, hudhook);
    			hud->BeginGroup();
    			// Add a control that will be linked to the cube. 
    			ViewportHUDControl* pControl = hud->AddControl(HUDCONTROL_TYPE_STATIC, doc, bd , cube, DescID(), BaseContainer(), GeData(), 0);
    			if (pControl == nullptr)
    				return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "couldn't create the hud element"_s);
    
    			maxon::Int32 dflags = pControl->GetDisplayFlags();
    			dflags |= HUDCONTROL_DFLAGS_ICON;
    			
    			
    
    			// pControl->SetLabel("this is my hud element"_s);
    			pControl->SetTopLeft(20, 20);
    			pControl->SetActiveMode(HUDCONTROL_AMODE_ALWAYS);
    			pControl->SetDisplayFlags(dflags);
    			pControl->SetFlag(HUDCONTROL_FLAG_COMMAND);
    			pControl->SetFlag(HUDCONTROL_FLAG_ACTION);
    			pControl->SetActionID(200000088); // this will active the move tool.
    			
    			const Filename icon = "mysupericon.tif"_s;
    			pControl->SetIconFile(doc, icon ); // you can define your own icon.
    
    		}
    
    		ViewportHUDControl* pGroup = hud->EndGroup();
    		if (pGroup)
    		{
    			pGroup->SetName("this is my group"_s);
    			pGroup->SetDisplayFlags(HUDCONTROL_DFLAGS_NAME);
    		}
    		doc->EndUndo();
    	}
    
    
    
    
    
    	return maxon::OK;
    }
    
    

    If i found something else, i'll get back
    cheers,
    Manuel



  • @m_magalhaes Thank you, this idea is good, I will to try it.

    Below I show examples of drawing using the python plug-in and C ++ plug-in in the picture. I am not very clear why they have the difference between drawing can be selected (python) and drawing cannot be selected (c ++).

    example.png



  • @m_magalhaes I found the reason!

    I used the example code like Draw manual

        return SUPER::Draw(op, drawpass, bd, bh);
    

    if use return DRAWRESULT::OK; it can be selected by selection tool!

        return DRAWRESULT::OK;
    

    it work,but why?😵

    example2.png



  • hello,

    while i could reproduce the behaviour with python i couldn't with c++ (even returning DRAWRESULT::OK)

    To reproduce it with python i have to not check the drawpass value.

    That mean i'm drawing my points on every single pass. (this is why those points appear even if the object is not selected.

    In c++ we are calling super::draw that mean the Object pass will draw nothing.

    if you add something like this:
    You draw will only draw durring the Object's pass. And will be visible event if the object is not selected.

    if drawpass != c4d.DRAWPASS_OBJECT :
                return c4d.DRAWRESULT_SKIP
    

    Could you provide your c++ code ?

    Cheers,
    Manuel



  • @m_magalhaes Thanks for the explanation, can help me better understand how it works!

    this version code can draw point but not be selected

        DRAWRESULT myplugin::Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh)
        {
            if (drawpass != DRAWPASS::OBJECT)
                return SUPER::Draw(op, drawpass, bd, bh);
            BaseContainer* data = op->GetDataInstance();
            Float32 size = 10.0;
            Vector color = Vector(1.0);
            Vector pos = Vector();
            const Matrix& mg = bh->GetMg();
            const Int32 cnt = 1;
            bd->SetMatrix_Matrix(op, mg);
            bd->SetPen(color);
            bd->SetPointSize(size);
            bd->DrawPointArray(cnt,&static_cast<Vector32>(pos));
            return SUPER::Draw(op, drawpass, bd, bh);
        }
    

    this version can draw and can be selected(only change return to --> return DRAWRESULT::OK)

        DRAWRESULT myplugin::Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh)
        {
            if (drawpass != DRAWPASS::OBJECT)
                return SUPER::Draw(op, drawpass, bd, bh);
            BaseContainer* data = op->GetDataInstance();
            Float32 size = 10.0;
            Vector color = Vector(1.0);
            Vector pos = Vector();
            const Matrix& mg = bh->GetMg();
            const Int32 cnt = 1;
            bd->SetMatrix_Matrix(op, mg);
            bd->SetPen(color);
            bd->SetPointSize(size);
            bd->DrawPointArray(cnt,&static_cast<Vector32>(pos));
            //
            return DRAWRESULT::OK;
        }


  • hello,

    ok i didn't set the matrix so my points were draw at the right spot but my "selectable" point were farther. That's why.

    kind of strange but you should not draw on that pass, that's maybe why.

    Cheers,
    Manuel



  • @m_magalhaes
    ok,It's a bit complicated😊


Log in to reply