Jump to content

bjlotus

Limited Member
  • Posts

    10
  • Joined

  • Last visited

About bjlotus

  • Birthday 06/15/1985

Profile Information

  • First Name
    Jon
  • Last Name
    B

HW | SW Information

  • OS
    Windows
  • CPU
    Intel

Recent Profile Visitors

781 profile views

bjlotus's Achievements

Newbie

Newbie (1/14)

  • Week One Done
  • One Month Later
  • One Year In

Recent Badges

2

Reputation

  1. Hi @zipit! oh, now I totally understand what you mean! (pun intended 😄) Thanks so much for the clarification; that would explain the tiny differences when I compared the results using your function. PS: it didn't sound pedantic at all! Best, Jon
  2. Hi @zipit, First of all, thank you so much for your reply and the super detailed comments on your code, it really helps me understand a few things (and hopefully to many other beginners as well). Your script does -almost- exactly what I was trying to do... and more importantly, the comments helps to grasp the hows and whys very clearly. Again, really appreciate your input, thanks 😄 I'm calculating the mean (i think) using the "normals_avg" variable. I add each cross product inside the for loop and then divide by the amount of polys selected. This was a quick example so I just calculated normals the way I remembered when I used to play with other software years ago. I'm not even checking if the polys are a triangle hehe... your GetPolygonNormal function is certainly more elegant. I compared the results and, while not always exactly the same, they are pretty close. Yeap, no flattening on the code I posted; what I was trying to do was: given a selection, first translate it by a fixed amount and then flatten it. The flatten part was what I didn't know how to do and what @Cairyn was kindly trying to explain. Sure thing! I know it's a bit messy and that there're probably some extra assignments, or things I should rewrite as functions; Being just an example I was just throwing lines testing what happens. I'm just starting to explore python's possibilities inside c4d (never used python before), so your version does definitely helps in many ways (even about how to keep things tidy!) Once again, thank you. Have a great day! Jon
  3. Hi @Cairyn, thanks again for your input! You're right about the flattening area position, I should use the average of the points and then mess with bounding boxes if needed, which of course can be tricky on odd shaped objects. Well, I'm a bit rusty when it comes to 3D to be honest. I'm not sure how I can create my flatten plane based on the avg normal and avg points... but rainy day ahead, so I'll be trying! Thanks! Jon
  4. Hi @Cairyn, thanks for your reply. I think I conceptually understand what you said, but I don't have a clue about how to implement it... I wrote a little example as an exercise, where I create a tube, select a couple polygons and translate the selected polygons based on the average normals. After that, I'd like to flatten out the selection... At some point I calculated the average points to see if that could be where the flattening might be applied (which is close to the modelling axis, when orientation is set to 'normals'), but I think I'd like to flatten where the selection starts, as shown in red on the following image: I've also added a couple colored nulls where the average normals (yellow) and average points (cyan) are, just for reference. import c4d from c4d import utils # ----------------------------------------------------------------------------------------------------------------------- # Main function # ----------------------------------------------------------------------------------------------------------------------- def main(): doc = c4d.documents.GetActiveDocument() #create an object and make it editable (use clone when using csto) obj = c4d.BaseObject(c4d.Otube) obj[c4d.PRIM_TUBE_IRAD] = 50 # inner rad obj[c4d.PRIM_TUBE_ORAD] = 100 # outer rad obj[c4d.PRIM_TUBE_HEIGHT] = 20 # height obj[c4d.PRIM_TUBE_SEG] = 12 # rotation segments obj[c4d.PRIM_TUBE_CSUB] = 1 # cap segments obj[c4d.PRIM_TUBE_HSUB] = 1 # height segments obj[c4d.PRIM_AXIS] = 2 # axis (2 = +Y) result = utils.SendModelingCommand( command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[obj.GetClone()], mode=c4d.MODELINGCOMMANDMODE_ALL, doc=doc) obj = result[0] # optimize the obj bc = c4d.BaseContainer() # contain settings # set optimize (default c4d) bc.SetFloat(c4d.MDATA_OPTIMIZE_TOLERANCE, .01) bc.SetBool(c4d.MDATA_OPTIMIZE_POINTS, True) bc.SetBool(c4d.MDATA_OPTIMIZE_POLYGONS, True) bc.SetBool(c4d.MDATA_OPTIMIZE_UNUSEDPOINTS, True) result = c4d.utils.SendModelingCommand( # optimize, result returns Boolean command=c4d.MCOMMAND_OPTIMIZE, list=[obj], doc=doc, bc=bc) obj.Message(c4d.MSG_UPDATE) # update object doc.InsertObject(obj) # add to scene selected_polys = obj.GetPolygonS() #get selected polys/base select #select arbitrary polys selected_polys.Select(9) selected_polys.Select(13) selected_points = [] #to hold point vectors selected_points_indexes = [] #to hold points indexes selected_polygons_indexes = [] #to hold polygons indexes polys_count = obj.GetPolygonCount() #get number of polys polys_list = selected_polys.GetAll(polys_count) #list of poly indexes holding boolean values: 1: selected, 0: not selected points = obj.GetAllPoints() # get all object points normals_avg = 0 #store average of normals #loop through polys, process if selected (true) for i in xrange(polys_count): if polys_list[i]: polygon = obj.GetPolygon(i) #get polygon selected_polygons_indexes.append(i) a, b, c, d = points[polygon.a], points[polygon.b], points[polygon.c], points[polygon.d] #there could be shared points on neighbour polys, this checks they're not added multiple times if a not in selected_points: selected_points.append(a) selected_points_indexes.append(polygon.a) if b not in selected_points: selected_points.append(b) selected_points_indexes.append(polygon.b) if c not in selected_points: selected_points.append(c) selected_points_indexes.append(polygon.c) if d not in selected_points: selected_points.append(d) selected_points_indexes.append(polygon.d) #cross product cross = (b - a).Cross(d - a).GetNormalized() #add to avg normals_avg += cross #calculate avg normals_avg = normals_avg / selected_polys.GetCount() doc.InsertObject(createColorNull(normals_avg, "normals_avg", 255, 255, 0), parent=None)#display a yellow null where normals_avg is #translate points offset = 30 # arbitrary amount in cm for i in xrange(len(selected_points)): obj.SetPoint(selected_points_indexes[i], selected_points[i] + normals_avg * offset) #update selected points points = obj.GetAllPoints() points_avg = 0 # average pos of selected points selected_points = [] #reset for i in xrange(len(selected_polygons_indexes)): polygon = obj.GetPolygon(selected_polygons_indexes[i]) # get polygon a, b, c, d = points[polygon.a], points[polygon.b], points[polygon.c], points[polygon.d] if a not in selected_points: selected_points.append(a) if b not in selected_points: selected_points.append(b) if c not in selected_points: selected_points.append(c) if d not in selected_points: selected_points.append(d) print("sel points", selected_points) #calculate avg points for i in xrange(len(selected_points)): points_avg += selected_points[i] points_avg = points_avg / len(selected_points) doc.InsertObject(createColorNull(points_avg, "points_avg", 0, 255, 255), parent=None) #display a cyan null where points_avg is obj.Message(c4d.MSG_UPDATE) # update object doc.Message(c4d.MSG_UPDATE) # update doc c4d.EventAdd() # refresh viewport # ----------------------------------------------------------------------------------------------------------------------- # Creates a color null/point # ----------------------------------------------------------------------------------------------------------------------- def createColorNull(pos, name, red, green, blue): null = c4d.BaseObject(c4d.Onull) if null is None: sys.exit('Could not create parent Null object!') null.SetName(name) null.SetRelPos(pos) null[c4d.NULLOBJECT_DISPLAY] = 1 null[c4d.NULLOBJECT_RADIUS] = 3 null[c4d.NULLOBJECT_ASPECTRATIO] = 1 null[c4d.NULLOBJECT_ORIENTATION] = 1 null[c4d.ID_BASEOBJECT_USECOLOR] = 2 null[c4d.NULLOBJECT_ICONCOL] = True r = c4d.utils.RangeMap(value=red, mininput=0, maxinput=255, minoutput=0, maxoutput=1, clampval=True) g = c4d.utils.RangeMap(value=green, mininput=0, maxinput=255, minoutput=0, maxoutput=1, clampval=True) b = c4d.utils.RangeMap(value=blue, mininput=0, maxinput=255, minoutput=0, maxoutput=1, clampval=True) null[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(r, g, b) return null # ----------------------------------------------------------------------------------------------------------------------- # Execute main() # ----------------------------------------------------------------------------------------------------------------------- if __name__ == '__main__': main() Any inputs on how should I continue to be able to flatten? Please keep in mind I'm kinda slow on this things 🙂 Thanks! Jon
  5. Hi all, I've been playing around with python inside c4d for the last couple days, just for the sake of learning something new (and open future creative possibilities, why not). I've been able to manipulate splines and polygons, create objects from scratch and send modelling commands... now, I want to do this 'simple thing' and I'm a bit stuck: I want to be able to 'flatten' a polygon selection based on the normals, like when you drag the scale axis to 0% on z handle when modelling. So far I've been able to move the selected polygons (or its points) based on the normal direction, but can't seem to get this one. Any hints will be greatly appreciated. PS: I know there're a few plugins around, but I just want to know how it works internally and the math involved, so I can try and implement a modelling sequence. Thanks! Jon
  6. Hi @jbatista, thanks for sharing, that's a really cool example. I think the main difference is that I need the motor/rotating piece not to be fixed, as you can see on JED's previous example (the top piece). Either way, the constraints on your project gave me some ideas to try! for example, I see you used different priorities -expression/animation- on your clamps. Thanks again Joao. @jed Yeah, I did that initially heh, but after many iterations changing the lengths and position it ended up pretty different. Jon
  7. Hi @jed, that's a looot closer! Thank you so much for tweaking the example. I'm gonna be playing with the alignment, position and lengths and see if I can get more even swing or different angles. While your example is almost what I actually need, for the sake of learning something -more- I'd also like to know if this could be done using contraints/IK... or maybe figure out the math behind it so it can be 100% xpresso. Thanks again!
  8. Thanks for link @Mike A, I'll download the simulator and explore what's possible! Thanks for the reference @Voytech, I remember that site! I've used some plugins by Jurgen in the past, I'll check those examples out and see if I can figure it out. In the meantime, I've tried to replicate what I want from @jed's example (from the other thread) using dynamics and connectors. It's not working properly, but I'm not sure why (yet). I've uploaded what I got so far. By the way, what I was trying to achieve specifically is something like this, around 3:43, which would result in an oscillating "fan" motion. 4bar_rig_dynamics_03.c4d
  9. Hi Mike, thanks for replying! Yes, Jed achieves the effect by using dynamics and connectors. I was wondering if a similar mechanism could be set up using constraints/IK. I'm watching a few tutorials to better understand what's possible. Thanks!
  10. Hi everyone, I've been trying to rig a simple 4-bar mechanism, in which 2 points are fixed. I want to achieve an oscillating motion, like the 1st one shown on the following gif, the one on the left: https://en.wikipedia.org/wiki/Four-bar_linkage#/media/File:Grashof_Type_I_Four-Bar_Kinematic_Inversions.gif I've seen an example using dynamics and connectors, but I was wondering if the same could be achieved using IK or constraints. I've tried a few setups but it's not working the way I expected. Any input or guidance will be greatly appreciated. Thanks! Jon
×
×
  • Create New...

Copyright Core 4D © 2023 Powered by Invision Community