Leaderboard
-
in all areas
- All areas
- Videos
- Video Comments
- Files
- File Comments
- File Reviews
- Pipelines Tools
- Pipeline Tool Comments
- Pipeline Tool Reviews
- Databases
- Database Comments
- Database Reviews
- Plugins
- Plugin Comments
- Plugin Reviews
- Images
- Image Comments
- Image Reviews
- Albums
- Album Comments
- Album Reviews
- Topics
- Posts
- Blog Entries
- Blog Comments
- Status Updates
- Status Replies
-
Custom Date
-
All time
May 3 2016 - April 19 2024
-
Year
April 19 2023 - April 19 2024
-
Month
March 19 2024 - April 19 2024
-
Week
April 12 2024 - April 19 2024
-
Today
April 19 2024
-
Custom Date
03/23/2021 - 03/23/2021
-
All time
Popular Content
Showing content with the highest reputation on 03/23/2021 in all areas
-
2 points
-
Hey, This helps a lot! Thank you for spending time on this. Exactly what I was looking for! ❤️1 point
-
This is not a beginner issue because beginners don't usually have Octane OR XP, which is why this was posted in the wrong section ! Although the question may be about splines, only people that have Octane can help you, so I have moved it where the people who do have Octane will see it. CBR1 point
-
1 point
-
Hate to say it, but you got a typo there. It's "Inquisitor" not "Inquistor". Unless it's on purpose ;D1 point
-
1 point
-
1 point
-
1 point
-
Works fine for me ... RS_Fresnel.c4d1 point
-
1 point
-
Just found this thread. When you use "Outline Polygons" you can determine the thickness of the uv line via the BP paint brush settings. The line will take the thickness of the brush.1 point
-
Here is a video I have made that should take you top the next stage. I can see you have been working hard on this so well done on your progress. This is 1080p so you may need for Youtube to process high res if its not showing yet1 point
-
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