For example I get from the Script Log
c4d.CallCommand(14046) # Split
Is there an Index page where I can see to what method that number belongs to ?
For example I get from the Script Log
c4d.CallCommand(14046) # Split
Is there an Index page where I can see to what method that number belongs to ?
Thank you very much for the hands-on example @ferdinand !
About "Islands" and "selections" terms.
As far as I know "Islands" are groups of polygons that are isolated from the rest of the object's geometry, similarly to the "Fill Bucket" of MS Painter in 2D if we choose a polygon of the mesh and apply the Grow Selection to it infinitely many times it will never reach the "Island" polygons.
Selections, well, they are selections we all know what those are but when you asked me if I was bridging Islands or Selections I didn't (and still don't) why it should matter. Doesn't the Bridge behave the same when connecting polygons be it Islands or Selections ? After all Selections are like islands in the sense that we isolate them from the rest of the mesh to apply modifications to them.
EDIT:
Ah ! the
settings.SetBool(c4d.MDATA_BRIDGE_FIRST_SELECT_ONLY, True)
settings.SetBool(c4d.MDATA_BRIDGE_SECOND_SELECT_ONLY, True)
They were at the bottom of the toolbridge.h with the rest of the UI-related Attributes that I didn't pay attention at all.... there's even a comment line.. how blind am I ?
About the Server Error
The zip containing my project I was trying to upload was 11,6 KB so I don't know what's wrong with that... tried again and failed. Tried a C4D file also and still failed.
The exact message:
Something went wrong while parsing server response
I am dropping the files in this text field to upload, should I be using a different method ? I don't want to externally link to them (like Dropbox or something else)
EDIT #2
Ah ! By islands you meant two different objects !
EDIT #3
I'm having constant crashes when trying to bridge polygon selections from the same object ...
Are there specific attributes that need to be left empty when bridging the same object with itself ?
For now I'll try to disconnect the target polygon selection and treat it as a different object in order to bridge it...
At this point I have no idea what the difference between "Polygon Islands" and "Polygon Selections" is ....
But yes, I have tried this with both two different objects and a single unified mesh of the two objects and didn't work. Exactly the same way I would do it manually as a user but this time I set polygon selections on the object and link them on the plugin generator to handle them.
"""
Minimal example of trying to use ID_MODELING_BRIDGE_TOOL programmatically
to bridge two polygon selections on a single merged object.
SETUP:
- Two cylinder objects with polygon selection tags
- Each tag selects polygons on one end cap
- We merge them with Connect, then try to bridge the selections
PROBLEM:
- With OBJINDEX1 only: C4D crashes
- With OBJINDEX1 and OBJINDEX3: C4D crashes
- With all four OBJINDEX: Returns False (no crash, but doesn't work)
"""
import c4d
from c4d import utils
def BridgePolygonSelections(doc):
"""
Attempt to bridge two polygon selections on a merged object
"""
# Get two source objects with polygon selection tags
obj1 = doc.SearchObject("Cylinder") # Has tag "Polygon Selection" with 9 polys selected
obj2 = doc.SearchObject("Cylinder 2") # Has tag "Polygon Selection" with 12 polys selected
if not obj1 or not obj2:
print("Objects not found")
return
# Clone the objects
clone1 = obj1.GetClone()
clone2 = obj2.GetClone()
# Get the polygon selection tags
tag1 = clone1.GetTag(c4d.Tpolygonselection)
tag2 = clone2.GetTag(c4d.Tpolygonselection)
if not tag1 or not tag2:
print("Selection tags not found")
return
# CRITICAL: Rename tags so Connect doesn't merge them into one
tag1.SetName("bridge_source")
tag2.SetName("bridge_target")
# Extract polygon indices from original tags
source_indices = []
target_indices = []
bs1 = tag1.GetBaseSelect()
bs2 = tag2.GetBaseSelect()
for i in range(clone1.GetPolygonCount()):
if bs1.IsSelected(i):
source_indices.append(i)
for i in range(clone2.GetPolygonCount()):
if bs2.IsSelected(i):
target_indices.append(i)
print(f"Source: {len(source_indices)} polygons")
print(f"Target: {len(target_indices)} polygons")
# Create temp document
temp_doc = c4d.documents.BaseDocument()
# Create Connect object and insert clones under it
connect = c4d.BaseObject(1011010)
temp_doc.InsertObject(connect)
clone1.InsertUnder(connect)
clone2.InsertUnder(connect)
# Execute passes to build Connect cache
temp_doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE)
# Make Connect editable to get merged polygon object
result = utils.SendModelingCommand(
command=c4d.MCOMMAND_CURRENTSTATETOOBJECT,
list=[connect],
mode=c4d.MODELINGCOMMANDMODE_ALL,
doc=temp_doc
)
if not result:
print("Failed to make Connect editable")
return
merged_obj = result[0]
print(f"Merged object: {merged_obj.GetPolygonCount()} polygons")
# Find the two selection tags on merged object
source_tag = None
target_tag = None
tag = merged_obj.GetFirstTag()
while tag:
if tag.GetName() == "bridge_source":
source_tag = tag
elif tag.GetName() == "bridge_target":
target_tag = tag
tag = tag.GetNext()
if not source_tag or not target_tag:
print("Tags not found on merged object")
return
# Extract actual polygon indices from merged object's tags
merged_source = []
merged_target = []
bs_src = source_tag.GetBaseSelect()
bs_tgt = target_tag.GetBaseSelect()
for i in range(merged_obj.GetPolygonCount()):
if bs_src.IsSelected(i):
merged_source.append(i)
if bs_tgt.IsSelected(i):
merged_target.append(i)
print(f"Merged source indices: {merged_source}")
print(f"Merged target indices: {merged_target}")
# Build bridge settings
settings = c4d.BaseContainer()
settings[c4d.MDATA_BRIDGE_RESTRICT] = True
# QUESTION: How to set OBJINDEX for polygon mode?
# Option 1: Only OBJINDEX1 (CRASHES C4D)
# settings[c4d.MDATA_BRIDGE_OBJINDEX1] = merged_obj
# Option 2: OBJINDEX1 and OBJINDEX3 (CRASHES C4D)
settings[c4d.MDATA_BRIDGE_OBJINDEX1] = merged_obj
settings[c4d.MDATA_BRIDGE_OBJINDEX3] = merged_obj
# Option 3: All four OBJINDEX (Returns False, doesn't crash)
# settings[c4d.MDATA_BRIDGE_OBJINDEX1] = merged_obj
# settings[c4d.MDATA_BRIDGE_OBJINDEX2] = merged_obj
# settings[c4d.MDATA_BRIDGE_OBJINDEX3] = merged_obj
# settings[c4d.MDATA_BRIDGE_OBJINDEX4] = merged_obj
# ELEMENT parameters - first and last polygon of each selection
settings[c4d.MDATA_BRIDGE_ELEMENT1] = merged_source[0] # 48
settings[c4d.MDATA_BRIDGE_ELEMENT2] = merged_source[-1] # 56
settings[c4d.MDATA_BRIDGE_ELEMENT3] = merged_target[0] # 19
settings[c4d.MDATA_BRIDGE_ELEMENT4] = merged_target[-1] # 30
# Other settings
settings[c4d.MDATA_BRIDGE_SUBDIVISION] = 0
settings[c4d.MDATA_BRIDGE_TENSION] = 0.0
settings[c4d.MDATA_BRIDGE_BOTH_MODE] = 0
print(f"Executing bridge...")
# Execute bridge
bridge_result = utils.SendModelingCommand(
command=c4d.ID_MODELING_BRIDGE_TOOL,
list=[merged_obj],
mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
bc=settings,
doc=temp_doc
)
print(f"Bridge result: {bridge_result}")
if bridge_result:
print("SUCCESS!")
else:
print("Bridge returned False")
# Run it
if __name__ == '__main__':
doc = c4d.documents.GetActiveDocument()
BridgePolygonSelections(doc)
I would post the full zip but I get a server error again... something must have broken on this forum with uploaded files as I had the same issue when trying to upload a screenshot
@ferdinand I'm still having trouble with this.
I'm trying to bridge polygon selections on a single merged object, but it keeps returning False.
My setup:
All settings:
python settings[MDATA_BRIDGE_RESTRICT] = True
settings[MDATA_BRIDGE_OBJINDEX1] = merged_obj
settings[MDATA_BRIDGE_OBJINDEX2] = merged_obj
settings[MDATA_BRIDGE_OBJINDEX3] = merged_obj
settings[MDATA_BRIDGE_OBJINDEX4] = merged_obj
settings[MDATA_BRIDGE_ELEMENT1] = 48 # First polygon of source selection
settings[MDATA_BRIDGE_ELEMENT2] = 56 # Last polygon of source selection
settings[MDATA_BRIDGE_ELEMENT3] = 19 # First polygon of target selection
settings[MDATA_BRIDGE_ELEMENT4] = 30 # Last polygon of target selection
//+ subdivision, tension, mode, etc.
The bridge tool returns False. The selections are verified to exist on the object (9 polygons at indices 48-56, and 12 polygons at indices 19-30).
Questions:
Thanks!
Oh ! we can bridge independent objects ? That simplifies things as I thought I would have to Connect+Delete first and then bridge...
Thank you for the explanation of the attribute calls.
Hello, I'm trying to use the Bridge Tool with the SendModelingCommand but I'm having trouble as there are attributes I don't know how to use. Could someone explain to me what these are for ?
MDATA_BRIDGE_ELEMENT1 = 1100, //LONG
MDATA_BRIDGE_ELEMENT2 = 1101, //LONG
MDATA_BRIDGE_ELEMENT3 = 1102, //LONG
MDATA_BRIDGE_ELEMENT4 = 1103, //LONG
MDATA_BRIDGE_OBJINDEX1 = 1104, //LINK
MDATA_BRIDGE_OBJINDEX2 = 1105, //LINK
MDATA_BRIDGE_OBJINDEX3 = 1106, //LINK
MDATA_BRIDGE_OBJINDEX4 = 1107, //LINK
MDATA_BRIDGE_DELETE = 1108, //BOOL
MDATA_BRIDGE_ISO = 1109, //BOOL
Also, given the type of elements I'm bridging and subsequently the modeling mode in which I will be using the Tool should I look out for specific things like the sequence of edges or points between the two parts to be connected ? Should I be treating Edge Selections like a sequence of point IDs or can I use them with their own IDs ?
Thank you for your time.
Ah ! They are called Proxy Tags and I can see the actual tag with the MSG_GETREALTAGDATA ! Thank you
️
I managed to solve this and make the Python Effector look like a plugin. I programmatically add the object, its icon and the script to it. But because it's impossible to add the User Data, I added them manually and then saved the project file containing the Effector object. Then added a simple condition if the scene file is present in the plugin folder merge the object to the current scene, else add the object without the User Data.
I think this solution is acceptable and elegant to present something as a complete plugin and not as a C4D scene file (usually a demonstration file) as I have encounter so far.
Is it possible to create a Python Effector plugin or there's only the Python Effector binder for that ?
I can't find a pure Python Plugin Effector object example.
I don't know how to make my object be accepted as an Effector on MoGraph generators Effector lists.
These attributes :
# MDATA_LOOP_FIRST_VERTEX = 1130, // LONG
# MDATA_LOOP_SECOND_VERTEX = 1131, // LONG
# MDATA_LOOP_POLYGON_INDEX = 1132, // LONG
and many more aren't documented here https://developers.maxon.net/docs/py/2026_1_0/cinema_resource/tool/toolloopselection.html
Is this an intended omission or a neglect ? should I be visiting the C++ SDK more often ?
And how do I see the data type and call ID for each of them in the documentation ? I don't see them here https://developers.maxon.net/docs/cpp/2026_1_0/toolloopselection_8h.html
(I would upload a screenshot but I get a server error about not being able to parse the file)