Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. mdr74
    3. Posts
    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups

    Posts made by mdr74

    RE: Enable Isoline Editing in tool plugin

    Thanks Ferdinand.
    with info=c4d.PLUGINFLAG_TOOL_EDITSTATES everything works fine.

    I mark your answer as correct.
    is it the right way to set the topic as solved?

    posted in Cinema 4D SDK •
    RE: Enable Isoline Editing in tool plugin

    @ferdinand
    😊 Thanks.
    I will be away in the next days.
    I will try it as soon as possible and inform you about the result.

    P.S . when the "info" is set as in your example, the isoline editing checkbox in the viewport configuration is automatically seen by the plugin or I have to configure the basedraw setting in the code?

    posted in Cinema 4D SDK •
    RE: Enable Isoline Editing in tool plugin

    @ferdinand
    Hi,
    here's the code ( a simplified version but with the same problem 😞 )

    import c4d, os, sys, pprint, itertools, math, random, time
    from dataclasses import dataclass, field
    from typing import List
    from itertools import islice
    from c4d import plugins, gui
    from c4d import utils as u
    from c4d import Vector as vc
    
    # Be sure to use a unique ID obtained from www.plugincafe.com
    TOOL_PLUGIN_ID = 1045691
    GET_KEYS = False
    DEBUG = False
    
    
    class TimeController(object):
        """This object makes sure to sleep as long as necessary to keep a specific
        time-rate."""
    
        def __init__(self, twait):
            self.twait = twait
            self.lastCall = 0
    
        def __call__(self):
            t = time.process_time()
            delta = t - self.lastCall
            if delta < self.twait:
                time.sleep(self.twait - delta)
            self.lastCall = time.process_time()
    
    
    class ToolSelector(c4d.plugins.ToolData):
        def __init__(self):
            self.obj = None
            self.base_select = None
            self.mouseCoordinate = None
            self.direction = None
            self.poly_sel_array = []
            self.pick_data = False
            self.selector_tag = None
    
        def InitTool(self, doc, data, bt):
            self.mouseCoordinate = None
            self.direction = None
            self.pick_data = False
            self.poly_sel_array = []
            self.selector_tag = None
            self.obj = None
    
            return True
    
        def InitObject(self, doc):
            if self.obj:
                self.base_select = self.obj.GetPolygonS()
                doc.SetActiveObject(self.obj, 0)
                doc.SetMode(c4d.Mpolygons)
    
            c4d.EventAdd()
    
            return True
    
    
        def FreeTool(self, doc, data):
            self.obj = None
    
        def GetState(self, doc):
            return c4d.CMD_ENABLED
    
        def Debug(self, msg):
            c4d.CallCommand(13957)  # Konsole loeschen
    
            return True
    
        def KeyboardInput(self, doc, data, bd, win, msg):
            key = msg.GetInt32(c4d.BFM_INPUT_CHANNEL)
            cstr = msg.GetString(c4d.BFM_INPUT_ASC)
            mod = msg.GetInt32(c4d.BFM_INPUT_QUALIFIER)
    
    
            if key == c4d.KEY_ESC:
                c4d.CallCommand(300001111)
    
                return True
    
    
            elif msg[c4d.BFM_INPUT_ASC] == "\t":
                self.pick_data = True
                c4d.DrawViews(
                        c4d.DRAWFLAGS_ONLY_ACTIVE_VIEW
                        | c4d.DRAWFLAGS_NO_THREAD
                        | c4d.DRAWFLAGS_NO_ANIMATION
                    )
                c4d.EventAdd()
    
                return True
    
            return False
    
        def CallViewportSelect(self, viewport_select, bd, doc):
            frame = bd.GetFrame()
            w = frame["cr"] - frame["cl"] + 1
            h = frame["cb"] - frame["ct"] + 1
    
            viewport_select.Init(
                w,
                h,
                bd,
                [self.obj],
                c4d.Mpolyedgepoint,
                True,
                c4d.VIEWPORTSELECTFLAGS_USE_HN | c4d.VIEWPORTSELECTFLAGS_USE_DEFORMERS | c4d.VIEWPORTSELECTFLAGS_FORCE_USE_DEFORMERS,
            )
    
        def MouseInput(self, doc, data, bd, win, msg):
            if not self.obj:
                self.obj = doc.GetActiveObject() if doc.GetActiveObject() else None
    
                if self.obj:
                    self.InitObject(doc)
                else:
                    return True
    
            bc = c4d.BaseContainer()
            pick_poly = None
    
            mouse_x = msg[c4d.BFM_INPUT_X]
            mouse_y = msg[c4d.BFM_INPUT_Y]
    
            myPoint = c4d.Vector(mouse_x, mouse_y, 0)
    
            viewport_select = c4d.utils.ViewportSelect()
            self.CallViewportSelect(viewport_select, bd, doc)
    
            win.MouseDragStart(c4d.KEY_MLEFT, mouse_x, mouse_y, c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE)
    
            if msg[c4d.BFM_INPUT_QUALIFIER] != c4d.QSHIFT:
                self.base_select.DeselectAll()
                self.poly_sel_array = []
    
            controller = TimeController(40 / 1000)
    
            while True:
                controller()
    
                result, m_deltax, m_deltay, channels = win.MouseDrag()
                delta = c4d.Vector(m_deltax, m_deltay, 0)
                myPoint = myPoint + delta
    
                if result == c4d.MOUSEDRAGRESULT_CONTINUE:
                    self.dragging = True
    
                    pick_poly = viewport_select.GetNearestPolygon(self.obj, int(myPoint.x), int(myPoint.y))
    
                    if pick_poly["i"] not in self.poly_sel_array:
                        self.poly_sel_array.append(pick_poly["i"])
    
                    doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, self.obj)
                    self.base_select.Select(pick_poly["i"])
    
                    c4d.DrawViews(
                        c4d.DRAWFLAGS_ONLY_ACTIVE_VIEW
                        | c4d.DRAWFLAGS_NO_THREAD
                        | c4d.DRAWFLAGS_NO_ANIMATION
                    )
    
                elif result in (c4d.MOUSEDRAGRESULT_FINISHED, c4d.MOUSEDRAGRESULT_ESCAPE):
                    self.dragging = False
                    break
    
            win.MouseDragEnd()
    
            if pick_poly:
                if pick_poly["i"] not in self.poly_sel_array:
                    self.poly_sel_array.append(pick_poly["i"])
    
            c4d.EventAdd()
    
            return True
    
        def Draw(self, doc, data, bd, bh, bt, flags):
    
            return c4d.DRAWRESULT_OK
    
        def GetCursorInfo(self, doc, data, bd, x, y, bc):
            if bc.GetId() == c4d.BFM_CURSORINFO_REMOVE:
                self.mouseCoordinate = c4d.Vector(-1)
                return True
    
            c4d.DrawViews()
    
            self.mouseCoordinate = c4d.Vector(x, y, 0)
    
            if self.pick_data:
                mouse_x = x
                mouse_y = y
    
                viewport_select = c4d.utils.ViewportSelect()
    
                pick_objects = viewport_select.PickObject(
                    bd, doc, int(mouse_x), int(mouse_y), rad=0, flags=c4d.VIEWPORT_PICK_FLAGS_0
                )
    
                if pick_objects:
                    if pick_objects[0] != self.obj:
                        self.poly_sel_array = []
    
                    self.obj = pick_objects[0]
    
                    while not isinstance(self.obj, c4d.PolygonObject):
                        self.obj = ObjectData(self.obj.GetDown())
    
    
                    self.InitObject(doc)
                    self.pick_data = False
    
                c4d.EventAdd()
                return True
    
            return True
    
        def AllocSubDialog(self, bc):
    
            return SettingsDialog(None)
    
    
    if __name__ == "__main__":
    
        plugins.RegisterToolPlugin(
            id=TOOL_PLUGIN_ID,
            str="Tool Selector",
            info=0,
            icon=None,
            help="tool selector",
            dat=ToolSelector(),
        )
    
    
    

    and two images to show what I'm trying to reach:

    with Mpolygons mode and the move tool active:

    image.jpg

    and when my tool is active:

    image.jpg

    what I meant with "expanding" is creating a tool that can remember the selection order of polygons.
    and use this selection for custom functions.

    thanks again 😊
    please tell me if you need more information

    posted in Cinema 4D SDK •
    RE: Enable Isoline Editing in tool plugin

    @ferdinand sorry to bother you again.
    I think I'm not able to exactly describe my request, maybe it's my poor english or bad terminology 😉

    I'm trying to create a tool plugin for expanding the selection tool with custom functionality.
    And when I switch to it, the isoline editing (still enabled in the basedraw) seems disabled in the viewport.

    If I edit a polygon object under HN I'd like to have the same display that I have with the move tool, but I have the same display of the loop cut tool. I don't know if it's possible or where I have to set a specific option (maybe in the draw method ?)

    I added this:

    print(bd[c4d.BASEDRAW_DATA_SDSEDIT])
    print(bd.IsViewOpen(doc))
    

    in the Draw and MouseInput method and the result is always 1 and True

    I'm using ViewportSelect GetNearestPolygon to select the polygon under the mouse.

    I hope it's everything clear...🤞

    thank you

    posted in Cinema 4D SDK •
    RE: Enable Isoline Editing in tool plugin

    Thank you.
    But I realise I used the wrong option.
    I was trying to enable the isoline editing while in polygon mode inside my tool.
    I know that some tools, like Loop cut for example, are not using isoline display, but I don't know if it's a choice or is it impossible to enable it.
    While using my tool, in the viewport settings the option is enabled, but I think it also depends on some unknown features

    Sorry for the confusion.
    Do you need me to change the post title?

    posted in Cinema 4D SDK •
    Enable Isoline Editing in tool plugin

    Hi, I'v searched the forum but I didn't find any solution.
    I'm developing a tool plugin with python for polygon manipulation.
    Is it possible to enable deformed isonline editing in the viewport for the selected object under a HN?

    thanks

    edit [ferdinand]: changed the title the word in the question

    posted in Cinema 4D SDK •
    RE: DEFORMCACHE AND MATRIX ISSUE

    Thanks a lot !!!.
    I will try it in the next days.
    I'm free for my personal projects only during weekends

    posted in Cinema 4D SDK •
    RE: DEFORMCACHE AND MATRIX ISSUE

    I don't know exactly how and why, but I found the solution.
    setting the basedraw matrix relative to the object when deformer is selected

    It's not a clean solution, but I cannot understand the hierarchy cache problem

    the modified method is:

    def DrawPolyNormals(self, obj):
            for p, n in zip(self.objPolysCenter, self.objPolysNormal):
                mx = self.mx
                if obj.GetDown():
                    if obj.GetDown().GetBit(c4d.BIT_ACTIVE):
                        self.basedraw.SetMatrix_Matrix(None, mx)
                    else:
                        self.basedraw.SetMatrix_Matrix(None, c4d.Matrix())
                normalDistance = n * self.normalLength
                q = p
                r = q + normalDistance * c4d.Matrix(v1=~mx.v1, v2=~mx.v2, v3=~mx.v3)
                self.basedraw.DrawLine(q, r, 0)
    

    the object points global position are calculated in self.objPolysCenter:

    def polysCenter(self, local=False):
            polys = self.polyPlgList
            pts = self.polyPtsList
            nbPolys = self.polyPlgCount
            center = vc()
    
            for i, poly in enumerate(self.polyPlgList):
                if poly.c != poly.d:
                    center = (pts[poly.a] + pts[poly.b] + pts[poly.c] + pts[poly.d]) / 4
                else:
                    center = (pts[poly.a] + pts[poly.b] + pts[poly.c]) / 3
                if not local:
                    yield center * self.mx
                else:
                    yield center
    
    posted in Cinema 4D SDK •
    RE: DEFORMCACHE AND MATRIX ISSUE

    @zipit
    I can wait, no hurry 😉

    Just to let you know...the same problem occurs with polygonal object and deformer
    everything's correct in world center but as soon as I move the object it seems that the matrix are calculated 2 times.
    It seems a cache issue

    I'm checking the link provided

    cheers

    posted in Cinema 4D SDK •
    RE: DEFORMCACHE AND MATRIX ISSUE

    @zipit
    Thanks

    I corrected the matrix calculation as suggested but the problem persist.
    I'll try to check the cache issue thread you linked

    for now I upload the plugin...it's very messy I think, but I use it also for testing other things ;):
    PLUGIN

    I also attach 2 screenshots of the problem

    when there is no deformer everything's correct (with base object and polygonal object):

    image.jpg

    as soon as I put a deformer below the lines shift away:

    image.jpg

    the same problem occurs when I change the deformer alignment to other planes and fit to parent:

    image.jpg

    thanks for the support

    posted in Cinema 4D SDK •
    DEFORMCACHE AND MATRIX ISSUE

    Hi,
    I'm trying to write a Tag plugin to visualise data on objects.
    Everything's work fine until I put a deformer under the object and get the deformed Cache.
    In that case, the matrix of the generated Lines are translated ( I think they are calculated twice or something similar ).

    this is the code:

    import random
    import os
    import sys
    import c4d
    from c4d import utils as u
    from c4d import Vector as vc
    
    PLUGIN_ID = 1099997
    # VIS_SETTINGS
    # POLYCENTERINFO
    # POLYNORMALINFO
    
    
    class PolyVisualiserHelper(object):
        def polysCenter(self, ob, local=True):
            polys = ob.GetAllPolygons()
            pts = ob.GetAllPoints()
            nbPolys = ob.GetPolygonCount()
            center = vc()
    
            for i, poly in enumerate(polys):
                if poly.c != poly.d:
                    center = (pts[poly.a] + pts[poly.b] + pts[poly.c] + pts[poly.d]) / 4
                else:
                    center = (pts[poly.a] + pts[poly.b] + pts[poly.c]) / 3
    
                yield center
    
    
        def polysNormal(self, ob, local=True):
            polys = ob.GetAllPolygons()
            pts = ob.GetAllPoints()
            nbPolys = ob.GetPolygonCount()
    
            norPolys = [vc()] * nbPolys
            nor = vc()
    
            for i, poly in enumerate(polys):
                nor = (pts[poly.a] - pts[poly.c]).Cross(pts[poly.b] - pts[poly.d])
                nor.Normalize()
    
                yield nor
    
    
        def DrawPolyNormals(self, bd, obj):
            ob = obj
            mx = ob.GetMg()
            for p, n in zip(self.polysCenter(ob), self.polysNormal(ob)):
                normalDistance = n * 50
                destV = p + normalDistance
                bd.DrawLine(p * mx, destV * mx, 0)
    
    
        def AccessCache(self, bd, op) :
            temp = op.GetDeformCache()
            if temp is not None:
              # recurse over the deformed cache
              self.AccessCache(bd, temp)
            else:
              # verify existance of the cache
              temp = op.GetCache()
              if temp is not None:
                  # recurve over the cache
                  self.AccessCache(bd, temp)
              else:
                  # the relevant data has been found
                  # and it should not be a generator
                  if not op.GetBit(c4d.BIT_CONTROLOBJECT) :
                      # check the cache is an instance of Opoint
                      if op.IsInstanceOf(c4d.Opoint) :
                          self.DrawPolyNormals(bd, op)
    
    
    class PolyVisualiser(c4d.plugins.TagData, PolyVisualiserHelper):
        """Look at Camera"""
    
        def Init(self, node):
            pd = c4d.PriorityData()
            if pd is None:
                raise MemoryError("Failed to create a priority data.")
    
            pd.SetPriorityValue(c4d.PRIORITYVALUE_CAMERADEPENDENT, True)
            node[c4d.EXPRESSION_PRIORITY] = pd
    
            return True
    
    
        def Draw(self, tag, op, bd, bh):
            self.AccessCache(bd, op)
    
            return c4d.DRAWRESULT_OK
    
    
    if __name__ == "__main__":
        # Retrieves the icon path
        directory, _ = os.path.split(__file__)
        fn = os.path.join(directory, "res", "polyNormal.png")
    
        # Creates a BaseBitmap
        bmp = c4d.bitmaps.BaseBitmap()
        if bmp is None:
            raise MemoryError("Failed to create a BaseBitmap.")
    
        # Init the BaseBitmap with the icon
        if bmp.InitWith(fn)[0] != c4d.IMAGERESULT_OK:
            raise MemoryError("Failed to initialize the BaseBitmap.")
    
        c4d.plugins.RegisterTagPlugin(id=PLUGIN_ID,
                                      str="Draw Test 03",
                                      info=c4d.TAG_EXPRESSION | c4d.TAG_VISIBLE | c4d.TAG_IMPLEMENTS_DRAW_FUNCTION,
                                      g=PolyVisualiser,
                                      description="drawtest03",
                                      icon=bmp)
    
    

    I already tried to disable the Matrix multiplication in the DrawPolyNormals() method when deformCache is generated but the matrix were still not correct

    thanks for future help

    posted in Cinema 4D SDK •
    RE: Send Python Code To C4D from any Texteditor

    @mikeudin I change this code in line 432 of SendPythonCodeToCinema4D.pyp

    str(code)
    

    with

    str(code, "utf-8")
    

    and also in lines 436, 440, 448

    the code returned to cinema4d was in byte format, not string.
    I'm not very good with python but it works for me

    posted in General Talk •
    RE: Send Python Code To C4D from any Texteditor

    @mikeudin thanks

    posted in General Talk •
    RE: Send Python Code To C4D from any Texteditor

    Hi,
    is it possible to update this fantastic tool for R23.
    I think it's broken due to new python 3.7 version, but I don't understand the socket module

    thanks

    posted in General Talk •
    RE: DrawHUDText returns a white box instead of a text?

    I discovered another problem in S22, maybe.
    The Hud text is correct but when I deselect the polygon object I cannot select anything in the viewport anymore.
    I don't know if it's a bug or an error in the plugin

    thanks again

    posted in Cinema 4D SDK •
    RE: DrawHUDText returns a white box instead of a text?

    it works.
    thanks

    posted in Cinema 4D SDK •
    RE: DrawHUDText returns a white box instead of a text?

    I started again from scratch and now it works but only in R21.
    In S22 here's no error in the console but nothing shows in the viewport (the object is a polygon).

    posted in Cinema 4D SDK •
    RE: DrawHUDText returns a white box instead of a text?

    Hi Manuel,
    I've tried to follow your example from the thread you linked but it gives me "Could not initialize global resource for the plugin"

    I thought it was solved, maybe something is changed in R21 or S22?

    thanks

    posted in Cinema 4D SDK •
    RE: Create object with custom icon in Python

    Found it

    I think it needs a string not an int

    nul = c4d.BaseObject(c4d.Onull)
    nul.SetName('New Test Icon')
    doc.InsertObject(nul)
        
    nul[c4d.ID_BASELIST_ICON_FILE] = "1021433"
    c4d.EventAdd()
    
    posted in Cinema 4D SDK •
    Create object with custom icon in Python

    Hi,
    I'm trying to write a python script to create a Null with a custom icon (with the same icon ID of the PBR light, just for test)
    but I cannot modify the icon.
    it give me no error so I don't know what's wrong

    thanks

    nul = c4d.BaseObject(c4d.Onull)
    nul.SetName('New Test Icon')
    doc.InsertObject(nul)
        
    nul[c4d.ID_BASELIST_ICON_FILE] = 1021433
    c4d.EventAdd()
    
    posted in Cinema 4D SDK •