Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/23/2021 in all areas

  1. Quad police, keep your standards high and your triangles low!
    2 points
  2. Let's say for arguments sake it's on purpose ๐Ÿ˜‚
    1 point
  3. Hate to say it, but you got a typo there. It's "Inquisitor" not "Inquistor". Unless it's on purpose ;D
    1 point
  4. Ha! Don't worry when I get home later I'll upload some ๐Ÿ˜‰
    1 point
  5. Thereยดs info on the bottom about functionality thru versions... "Note: plugin is written to work with R16 upto R20. Not tested on R21/S22. Will not work with R23 (yet). "
    1 point
  6. I'm on R23 and have this info : Probably python3 issue...
    1 point
  7. Vectron industries, for all your hoverboard needs!
    1 point
  8. Hi @bjlotus, hi @Cairyn, there is one problem with your normals calculation. You calculate just a vertex normal in the polygon and then declare it to be the polygon normal ๐Ÿ˜‰ (your variable "cross"), i.e., you assume all your polygons to be coplanar. With today's high density meshes you can probably get away with that to a certain degree, but it would not hurt to actually calculate the mean vertex normal of a polygon, a.k.a., the polygon normal to have a precise result. The problem with your "flattening" is that it is not one. Unless I have overread something here in the thread, the missing keyword would be a point-plane projection. You just translate all selected points by a fixed amount, which was if I understood that correctly only a work in progress, but obviously won't work. Things could also be written a bit more tidely and compact in a pythonic fashion, but that has very little impact on the performance and is mostly me being nitpicky ๐Ÿ˜‰ I did attach a version of how I would do this at the end (there are of course many ways to do this, but maybe it will help you). Cheers, Ferdinand """'Flattens' the active polygon selection of a PolygonObject. Projects the points which are part of the active polygon selection into the mean plane of the polygon selection. """ import c4d def GetMean(collection): """Returns the mean value of collection. In Python 3.4+ we could also use statistics.mean() instead. Args: collection (iterable): An iterable of types that support addition, whose product supports multiplication. Returns: any: The mean value of collection. """ return sum(collection) * (1. / len(collection)) def GetPolygonNormal(cpoly, points): """Returns the mean of all vertex normals of a polygon. You could also use PolygonObject.CreatePhongNormals, in case you expect to always have a phong tag present and want to respect phong breaks. Args: cpoly (c4d.Cpolygon): A polygon. points (list[c4d.vector]): All the points of the object. Returns: c4d.Vector: The polygon normal. """ # The points in question. a, b, c, d = (points[cpoly.a], points[cpoly.b], points[cpoly.c], points[cpoly.d]) points = [a, b, c] if c == d else [a, b, c, d] step = len(points) - 1 # We now could do some mathematical gymnastics to figure out just two # vertices we want to use to compute the normal of the two triangles in # the quad. But this would not only be harder to read, but also most # likely slower. So we are going to be 'lazy' and just compute all vertex # normals in the polygon and then compute the mean value for them. normals = [] for i in range(step + 1): o = points[i - 1] if i > 0 else points[step] p = points[i] q = points[i + 1] if i < step else points[0] # The modulo operator is the cross product. normals.append(((p - q)) % (p - o)) # Return the normalized (with the inversion operator) mean of them. return ~GetMean(normals) def ProjectOnPlane(p, q, normal): """Projects p into the plane defined by q and normal. Args: p (c4d.Vector): The point to project. q (c4d.Vector): A point in the plane. normal (c4d.Vector): The normal of the plane (expected to be a unit vector). Returns: c4d.Vector: The projected point. """ # The distance from p to the plane. distance = (p - q) * normal # Return p minus that distance. return p - normal * distance def FlattenPolygonSelection(node): """'Flattens' the active polygon selection of a PolygonObject. Projects the points which are part of the active polygon selection into the mean plane of the polygon selection. Args: node (c4d.PolygonObject): The polygon node. Returns: bool: If the operation has been carried out or not. Raises: TypeError: When node is not a c4d.PolygonObject. """ if not isinstance(op, c4d.PolygonObject): raise TypeError("Expected a PolygonObject for 'node'.") # Get the point, polygons and polygon selection of the node. points = node.GetAllPoints() polygons = node.GetAllPolygons() polygonCount = len(polygons) baseSelect = node.GetPolygonS() # This is a list of booleans, e.g., for a PolygonObject with three # polygons and the first and third polygon being selected, it would be # [True, False, True]. polygonSelection = baseSelect.GetAll(polygonCount) # The selected polygons and the points which are part of these polygons. selectedPolygonIds = [i for i, v in enumerate(polygonSelection) if v] selectedPolygons = [polygons[i] for i in selectedPolygonIds] selectedPointIds = list({p for cpoly in selectedPolygons for p in [cpoly.a, cpoly.b, cpoly.c, cpoly.d]}) selectedPoints = [points[i] for i in selectedPointIds] # There is nothing to do for us here. if not polygonCount or not selectedPolygons: return False # The polygon normals, the mean normal and the mean point. The mean point # and the mean normal define the plane we have to project into. Your # image implied picking the bottom plane of the bounding box of the # selected vertices as the origin of the plane, you would have to do that # yourself. Not that hard to do, but I wanted to keep things short ;) polygonNormals = [GetPolygonNormal(polygons[pid], points) for pid in selectedPolygonIds] meanNormal = ~GetMean(polygonNormals) meanPoint = GetMean(selectedPoints) # Project all the selected points. for pid in selectedPointIds: points[pid] = ProjectOnPlane(points[pid], meanPoint, meanNormal) # Create an undo, write the points back into the polygon node and tell # it that we did modify it. doc.StartUndo() doc.AddUndo(c4d.UNDOTYPE_CHANGE, node) node.SetAllPoints(points) doc.EndUndo() node.Message(c4d.MSG_UPDATE) # Things went without any major hiccups :) return True def main(): """Entry point. """ if FlattenPolygonSelection(op): c4d.EventAdd() if __name__ == '__main__': main()
    1 point
ร—
ร—
  • Create New...