Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. indexofrefraction
    indexofrefraction

    indexofrefraction

    @indexofrefraction

    6
    Reputation
    128
    Posts
    167
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    indexofrefraction Follow

    Best posts made by indexofrefraction

    RE: Check for missing textures

    ok! finally, it is imporant to use the doc to get the irs !
    now it works.

    irs = c4d.modules.render.InitRenderStruct(doc)
    

    but question:
    is this the only / best way to check if textures are missing?

    an alternative would be to actually check if the file is existing somewhere in the given paths

    posted in Cinema 4D SDK •
    RE: The layer material ID is the same as the node material ID.

    I also just ran into this...
    < R24 you dont have BaseList2D.IsNodeBased, but as a small hack you can do:

    def isNodeMaterial(op):
      return True if op.GetType == c4d.Mmaterial and '[Node]' in op.GetBubbleHelp() else False
    
    posted in General Talk •
    RE: Check for missing textures

    hi and thanks Maxime !

    GetAllAssetsNew() is S22 only,
    and I had problems with InitRender() and Vray Bitmaps

    so I decided to manually check for the files...
    I had it already, but GenerateTexturePath() shortens the code quite a bit, because I dont have to check all possible paths.

    It seem GenerateTexturePath() returns the absolute path, if the file is found somewhere in the texture paths, otherwise it returns None.

    needs some testing, but until now it seems to work well.

    best, index

    posted in Cinema 4D SDK •
    Quicktab Radio UserData change results in 2 Messages (Mini-Bug?)

    Hi,

    Just FYI ...
    I just noticed, that a Quicktab Radio UserData change results in two Messages (with the same UserData ID)
    If I change the interface to Cycle, I get only one Message as expected for an UserData change.

    This might be a tiny miny Bug (?) 🙂

    index

    posted in Cinema 4D SDK •
    CommandData Plugin with Submenu

    Hi,

    below is a simple CommandData plugin with a submenu to invoke different actions.

    This works fine if more than one of these plugins (with unique Plugin Ids ofc) are in one plugin folder.
    But there is no menu if there is only one plugin present in the folder.

    Is there a way to create such a menu with one plugin, while not registering each menu point as separate command?

    best index

    # encoding: utf-8
    
    ''' CommandData Plugin with Menu '''
    
    import c4d 
    
    PLUGIN_ID = 12345678  # Unique Plugin Id
    
    MENUID_CMD0 = 1000
    MENUID_CMD1 = 1001
    
    class MenuHandler(c4d.plugins.CommandData):
    
    	def Register(self):
    		return c4d.plugins.RegisterCommandPlugin(
    			id=PLUGIN_ID, str="Test", info=c4d.PLUGINFLAG_COMMAND_HOTKEY, icon=None, help=None, dat=MenuHandler())
    
    	def GetSubContainer(self, doc, submenu):
    		bc = c4d.BaseContainer()
    		bc.SetString(1, "Test")
    		bc.SetString(MENUID_CMD0, "Command 0")
    		bc.SetString(MENUID_CMD1, "Command 1")
    		submenu.InsData(0, bc)
    		return True
    
    	def ExecuteSubID(self, doc, id):
    		if id == MENUID_CMD0:
    			pass
    		if id == MENUID_CMD1:
    			pass
    		return True
    
    	def Execute(self, doc):
    		return True
    
    if __name__ == "__main__":
    	MenuHandler().Register()
    
    posted in Cinema 4D SDK •
    RE: incorrect specular channel property ids

    tx, i just wanted to report it...

    posted in Cinema 4D SDK •

    Latest posts made by indexofrefraction

    RE: Insert a shader into a shader hierarchy

    Thanks a lot kbar.. i'll watch and learn!
    still... the hurdles to compile a c++ plugin are extremely high nowadays. 😕
    it would be great if the sdk plugins would be downloadable ready compiled as well

    posted in Cinema 4D SDK •
    RE: Insert a shader into a shader hierarchy

    this "Active Object Dialog" plugin looks very interesting
    if it would be understandably described how to compile it / the c++ sdk, we could check it out
    but sadly this got so complicated that you need a degree in IT to do it. .-)

    posted in Cinema 4D SDK •
    developers.maxon.net - offline

    FYI, developers.maxon.net is down since about 24 hours....

    posted in General Talk •
    RE: Gimbal Lock Safe Target Expression

    I have found another way to do this, which is maybe better (?)
    because it seems to work around tackling with parallel vectors....

    LookAtCamera::Execute() translated to python ... 🙂
    https://github.com/PluginCafe/cinema4d_cpp_sdk_extended/blob/master/plugins/cinema4dsdk/source/tag/lookatcamera.cpp

    def lookat(op, target, pitch=True):
      ''' orient op to look at target '''
      local = (~(op.GetUpMg() * op.GetFrozenMln())) * target.GetMg().off - op.GetRelPos()
      hpb = c4d.utils.VectorToHPB(local)
      if not pitch: hpb.y = op.GetRelRot().y
      hpb.z = op.GetRelRot().z
      op.SetRelRot(hpb)
      c4d.EventAdd()
    

    It seems to work fine... but for clarity... after checking the Matrix Manual (see end of the page) ...
    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/manuals/data_algorithms/classic_api/matrix.html?highlight=matrix

    Is this correct / covers all cases to get the targets position in local space?
    (~(op.GetUpMg() * op.GetFrozenMln())) * target.GetMg().off
    specifically.. what is
    m = utils.MatrixMove(op.GetAbsPos()) * utils.HPBToMatrix(op.GetAbsRot()) * utils.MatrixScale(op.GetAbsScale())
    in this context? (ps. GetAbsScale misses the brackets in the docs)

    and... is this the real code of the Target Tag ?

    posted in Cinema 4D SDK •
    RE: Gimbal Lock Safe Target Expression

    Hi Ferdinand, yes all solved
    and sorry if the gimbal lock was a false interpretation of what was happening.
    From reading the old threads I thought the quaternion solution was mandatory to solve this.

    for clarity and as an example I'm including a comparison of
    your solution (working) and riccardos solution (showing the flip)

    spotLight.c4d

    but for me the case is closed...
    Thanks a lot for helping with this !

    posted in Cinema 4D SDK •
    RE: Gimbal Lock Safe Target Expression

    Hi Ferdinand,

    thanks a lot, seems I'm not the only one missing the good weather outside .-)

    The code in the first lookat() function should be abs(ri.x - 1.0),
    this comes from the post in the mentioned link. I corrected that in the original post.
    (it was just missing in the post, my code had the ri.x)

    what I'm on to is a 2 axis ceiling spot.
    its a null with a python tag having a target link userdata, then inside a hierarchy with two axes.
    atm they are driven by 2 target tags (initialized by the pyTag) one needs pitch on, one needs pitch off.
    this works fine, but as i have 900 of these in a file,
    i am trying to get rid of the target tags and do all in the pyTag.
    I can post the file tomorrow.

    what happens with my lookat() is that if you move the target,
    the spot sometimes turns upside down 180 degrees and sticks in the ceiling.

    with lookatQ() the spot simply doesn't point in the correct direction.
    but it would be very interesting to learn how to do it with quaternions.

    edit: your solution seems to work nicely, btw!
    p.s. i guess ~ is normalise and % is the cross product

    posted in Cinema 4D SDK •
    Gimbal Lock Safe Target Expression

    Hi,
    I have seen and as expected this was discussed already in the past, but I could not find any working example in this forum.

    I'd simply like to have a (gimbal lock safe) python replacement for the Target (Expression) Tag.

    I'm attaching what I have come up with until now...
    two versions #1 without , #2 with quaternion --> sadly #1 has gimbal issues and #2 fails completely
    both with a pitch lock like in the Target Tag --> sure this could be done more elegant .-)

    It was stated in one of the (below) mentioned threads, that support can't solve such problems for the users,
    but this would be such a valuable tool in the quiver that it might be an exception (?)

    best, index

    def lookat(op, target, pitchlock=0):
        ''' gimbal lock UNSAFE target expression
            this basically works, but results in axis flips sometimes '''
        r1 = op.GetRelRot() # backup
    
        p1 = op.GetMg().off # from
        p2 = target.GetMg().off # to
        tmp = c4d.Vector(0, 1, 0) # temp-up
        fo = (p2 - p1).GetNormalized() # forward
        ri = tmp.Cross(fo).GetNormalized() # right
        up = fo.Cross(ri).GetNormalized() # up
    
        # https://plugincafe.maxon.net/topic/11152/object-target-expression-in-python/2
        # try to mitigate gimbal-lock --> UNSAFE, RESULTS IN AXIS FLIPS !
        if (fo + tmp).z < 0: up.x = -up.x
        if abs(ri.x - 1.0) < 0.001: ri = -ri
    
        m = c4d.Matrix()
        m.v1 = ri
        m.v2 = up
        m.v3 = fo
        m.off = p1
        op.SetMg(m)
    
        if pitchlock:
            r = op.GetRelRot()
            op.SetRelRot(c4d.Vector(r.x, r1.y, r.z))
    
    def lookatQ(op, target, pitchlock=0):
        ''' quaternion based (gimbal lock safe ???) target expression
            sadly doesn't work and results in a wrong rotation '''
    
        r1 = op.GetRelRot() # backup
    
        p1 = op.GetMg().off # from
        p2 = target.GetMg().off # to
        tmp = c4d.Vector(0, 1, 0) # temp-up
        fo = (p2 - p1).GetNormalized() # forward
        ri = tmp.Cross(fo).GetNormalized() # right
        up = fo.Cross(ri).GetNormalized() # up
    
        # copied from
        # https://www.gamedev.net/forums/topic/613595-quaternion-lookrotationlookat-up/
        w = math.sqrt(1.0 + ri.x + up.y + fo.z) * 0.5
        w4_recip = 1.0 / (4.0 * w)
        x = (up.z - fo.y) * w4_recip
        y = (fo.x - ri.z) * w4_recip
        z = (ri.y - up.x) * w4_recip
    
        # given the above is correct, is this correctly applied here ???
        q = c4d.Quaternion()
        v = c4d.Vector(x, y, z)
        q.SetAxis(v, w)
        m = q.GetMatrix()
        m.off = p1
        op.SetMg(m)
    
        if pitchlock:
            r = op.GetRelRot()
            op.SetRelRot(c4d.Vector(r.x, r1.y, r.z))
    
    posted in Cinema 4D SDK •
    RE: Osubdivisionsurface ?

    ups, sorrryy. my bad .-)

    I know that list ... but LOL,
    now i cant find the object type for the Cloner Object 🦌

    posted in Cinema 4D SDK •
    Osubdivisionsurface ?

    hi.. just to report....

    the object type for the Subdivision Surface object seems to be missing in the python and C++ sdk...

    c4d.Osubdivisionsurface = 1007455

    best, index

    posted in Cinema 4D SDK •
    RE: Insert a shader into a shader hierarchy

    hi Ferdinand,

    i noticed that there is actually an issue with excessive gelist heads....
    if you have this :

    <c4d.BaseShader object called 'Filter/Filter' with ID 1011128 at 0x7fcebe74eeb0>
    + <c4d.GeListHead object at 0x7fcebe787a70> branch 'Shaders'
    + + <c4d.LayerShader object called 'Layer/Layer' with ID 1011123 at 0x7fcebe787ab0>
    + + + <c4d.BaseShader object called 'Noise/Noise' with ID 1011116 at 0x7fcebe787b90>
    

    GetUp() on the LayerShader seems to return None,
    which is a problem if - like in this case - you need to know if a shader is in the middle inside a shader tree,
    or if it is at the top / a direct child of the material

    this makes something like this necessary to properly "insert" a shader ....

    if isinstance(target, c4d.BaseShader): 
        shader.InsertUnder(target)
    else:
        target.InsertShader(shader)
    
    posted in Cinema 4D SDK •