From 95b26a40af165c6858951e3cc89aba593270c00f Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Thu, 16 Nov 2023 16:35:54 +0100 Subject: [PATCH] added shape to brep and brep from/to iges --- CHANGELOG.md | 14 + src/compas/brep/brep.py | 223 +++++++++---- src/compas/data/samples/tubemesh.obj | 406 ++++++++++++------------ src/compas/datastructures/mesh/join.py | 3 +- src/compas/geometry/shapes/box.py | 73 +++-- src/compas/geometry/shapes/capsule.py | 22 +- src/compas/geometry/shapes/cone.py | 12 + src/compas/geometry/shapes/cylinder.py | 22 +- src/compas/geometry/shapes/sphere.py | 21 +- src/compas/geometry/shapes/torus.py | 32 +- src/compas/geometry/surfaces/surface.py | 15 +- 11 files changed, 519 insertions(+), 324 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e14b1a77ea7..887e19ac8b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* Added `compas.geometry.Box.to_brep()`. +* Added `compas.geometry.Cone.to_brep()`. +* Added `compas.geometry.Cylinder.to_brep()`. +* Added `compas.geometry.Sphere.to_brep()`. +* Added `compas.geometry.Torus.to_brep()`. +* Added `compas.brep.Brep.from_iges()`. +* Added `compas.brep.Brep.to_iges()`. + ### Changed +* Changed `compas.geometry.NurbsSurface.u_space` to `space_u`. +* Changed `compas.geometry.NurbsSurface.v_space` to `space_v`. +* Changed `compas.geometry.NurbsSurface.u_isocurve` to `isocurve_u`. +* Changed `compas.geometry.NurbsSurface.v_isocurve` to `isocurve_v`. +* Changed `compas.brep.Brep.from_step_file` to `from_step`. + ### Removed diff --git a/src/compas/brep/brep.py b/src/compas/brep/brep.py index b824e17c5a7..3f78e895e58 100644 --- a/src/compas/brep/brep.py +++ b/src/compas/brep/brep.py @@ -12,12 +12,17 @@ def new_brep(*args, **kwargs): @pluggable(category="factories") -def from_native(*args, **kwargs): +def from_boolean_difference(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_mesh(*args, **kwargs): +def from_boolean_intersection(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_boolean_union(*args, **kwargs): raise PluginNotInstalledError() @@ -26,38 +31,53 @@ def from_box(*args, **kwargs): raise PluginNotInstalledError() +@pluggable(category="factories") +def from_brepfaces(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_cone(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_curves(*args, **kwargs): + raise PluginNotInstalledError() + + @pluggable(category="factories") def from_cylinder(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_sphere(*args, **kwargs): +def from_extrusion(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_cone(*args, **kwargs): +def from_iges(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_surface(*args, **kwargs): +def from_loft(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_torus(*args, **kwargs): +def from_mesh(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_sweep(*args, **kwargs): +def from_native(*args, **kwargs): raise PluginNotInstalledError() @pluggable(category="factories") -def from_step_file(*args, **kwargs): +def from_pipe(*args, **kwargs): raise PluginNotInstalledError() @@ -67,7 +87,27 @@ def from_polygons(*args, **kwargs): @pluggable(category="factories") -def from_curves(*args, **kwargs): +def from_sphere(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_step(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_surface(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_sweep(*args, **kwargs): + raise PluginNotInstalledError() + + +@pluggable(category="factories") +def from_torus(*args, **kwargs): raise PluginNotInstalledError() @@ -342,49 +382,49 @@ def centroid(self): # ============================================================================== @classmethod - def from_native(cls, native_brep): - """Creates a Brep from an instance of a native backend Brep type. + def from_box(cls, box): + """Construct a Brep from a COMPAS box. Parameters ---------- - brep : an instance of a Brep from a supported Brep backend - e.g. Rhino.Geometry.Brep + box : :class:`~compas.geometry.Box` Returns ------- :class:`~compas.geometry.Brep` + """ - return from_native(native_brep) + return from_box(box) @classmethod - def from_step_file(cls, filename): - """Conctruct a Brep from the data contained in a STEP file. + def from_brepfaces(cls, faces): + """Make a Brep from a list of Brep faces forming an open or closed shell. Parameters ---------- - filename : str + faces : list[:class:`~compas.geometry.BrepFace`] Returns ------- :class:`~compas.geometry.Brep` """ - return from_step_file(filename) + return from_brepfaces(faces) @classmethod - def from_polygons(cls, polygons): - """Construct a Brep from a set of polygons. + def from_cone(cls, cone): + """Construct a Brep from a COMPAS cone. Parameters ---------- - polygons : list[:class:`~compas.geometry.Polygon`] + cone : :class:`~compas.geometry.Cone` Returns ------- :class:`~compas.geometry.Brep` """ - return from_polygons(polygons) + return from_cone(cone) @classmethod def from_curves(cls, curves): @@ -402,127 +442,163 @@ def from_curves(cls, curves): return from_curves(curves) @classmethod - def from_box(cls, box): - """Construct a Brep from a COMPAS box. + def from_cylinder(cls, cylinder): + """Construct a Brep from a COMPAS cylinder. Parameters ---------- - box : :class:`~compas.geometry.Box` + cylinder : :class:`~compas.geometry.Cylinder` Returns ------- :class:`~compas.geometry.Brep` """ - return from_box(box) + return from_cylinder(cylinder) @classmethod - def from_sphere(cls, sphere): - """Construct a Brep from a COMPAS sphere. + def from_extrusion(cls, curve, vector): + """Construct a Brep by extruding a closed curve along a direction vector. Parameters ---------- - sphere : :class:`~compas.geometry.Sphere` + curve : :class:`~compas.geometry.Curve` + The curve to extrude + vector : :class:`~compas.geometry.Vector` + The vector to extrude the curve by Returns ------- :class:`~compas.geometry.Brep` """ - return from_sphere(sphere) + return from_extrusion(curve, vector) @classmethod - def from_cylinder(cls, cylinder): - """Construct a Brep from a COMPAS cylinder. + def from_iges(cls, filename): + """Construct a Brep from the data contained in an IGES file. Parameters ---------- - cylinder : :class:`~compas.geometry.Cylinder` + filename : str Returns ------- :class:`~compas.geometry.Brep` """ - return from_cylinder(cylinder) + return from_iges(filename) @classmethod - def from_cone(cls, cone): - """Construct a Brep from a COMPAS cone. + def from_loft(cls, curves): + """Construct a Brep by lofting a set of curves. Parameters ---------- - cone : :class:`~compas.geometry.Cone` + curves : list[:class:`~compas.geometry.Curve`] Returns ------- :class:`~compas.geometry.Brep` """ - return from_cone(cone) + return from_loft(curves) @classmethod - def from_torus(cls, torus): - """Construct a Brep from a COMPAS torus. + def from_mesh(cls, mesh): + """Construct a Brep from a COMPAS mesh. Parameters ---------- - torus : :class:`~compas.geometry.Torus` + mesh : :class:`~compas.datastructures.Mesh` Returns ------- - :class:`~compas.geometry.BRep` + :class:`~compas.geometry.Brep` """ - return from_torus(torus) + return from_mesh(mesh) @classmethod - def from_mesh(cls, mesh): - """Construct a Brep from a COMPAS mesh. + def from_native(cls, native_brep): + """Creates a Brep from an instance of a native backend Brep type. Parameters ---------- - mesh : :class:`~compas.datastructures.Mesh` + brep : an instance of a Brep from a supported Brep backend + e.g. Rhino.Geometry.Brep + + Returns + ------- + :class:`~compas.geometry.Brep` + """ + return from_native(native_brep) + + @classmethod + def from_pipe(cls, curve, radius, thickness=None): + """Construct a Brep by extruding a closed curve along a path curve. + + Parameters + ---------- + curve : :class:`~compas.geometry.Curve` + The curve to extrude + radius : float + The radius of the pipe. + thickness : float, optional + The thickness of the pipe. + The thickness should be smaller than the radius. Returns ------- :class:`~compas.geometry.Brep` """ - return from_mesh(mesh) + return from_pipe(curve, radius, thickness=thickness) @classmethod - def from_brepfaces(cls, faces): - """Make a Brep from a list of Brep faces forming an open or closed shell. + def from_polygons(cls, polygons): + """Construct a Brep from a set of polygons. Parameters ---------- - faces : list[:class:`~compas.geometry.BrepFace`] + polygons : list[:class:`~compas.geometry.Polygon`] Returns ------- :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_polygons(polygons) @classmethod - def from_extrusion(cls, curve, vector): - """Construct a Brep by extruding a closed curve along a direction vector. + def from_sphere(cls, sphere): + """Construct a Brep from a COMPAS sphere. Parameters ---------- - curve : :class:`~compas.geometry.Curve` - The curve to extrude - vector : :class:`~compas.geometry.Vector` - The vector to extrude the curve by + sphere : :class:`~compas.geometry.Sphere` Returns ------- :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_sphere(sphere) + + @classmethod + def from_step(cls, filename): + """Conctruct a Brep from the data contained in a STEP file. + + Parameters + ---------- + filename : str + + Returns + ------- + :class:`~compas.geometry.Brep` + + """ + return from_step(filename) @classmethod def from_sweep(cls, profile, path): @@ -540,7 +616,22 @@ def from_sweep(cls, profile, path): :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_sweep(profile, path) + + @classmethod + def from_torus(cls, torus): + """Construct a Brep from a COMPAS torus. + + Parameters + ---------- + torus : :class:`~compas.geometry.Torus` + + Returns + ------- + :class:`~compas.geometry.BRep` + + """ + return from_torus(torus) # ============================================================================== # Boolean Constructors @@ -560,7 +651,7 @@ def from_boolean_difference(cls, brep_a, brep_b): :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_boolean_difference(brep_a, brep_b) @classmethod def from_boolean_intersection(cls, brep_a, brep_b): @@ -576,7 +667,7 @@ def from_boolean_intersection(cls, brep_a, brep_b): :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_boolean_intersection(brep_a, brep_b) @classmethod def from_boolean_union(cls, brep_a, brep_b): @@ -592,7 +683,7 @@ def from_boolean_union(cls, brep_a, brep_b): :class:`~compas.geometry.Brep` """ - raise NotImplementedError + return from_boolean_union(brep_a, brep_b) def __sub__(self, other): """Compute the boolean difference using the "-" operator of this shape and another. @@ -837,7 +928,7 @@ def cull_unused_vertices(self): None """ - NotImplementedError + raise NotImplementedError def cull_unused_edges(self): """Remove all unused edges. @@ -847,7 +938,7 @@ def cull_unused_edges(self): None """ - NotImplementedError + raise NotImplementedError def cull_unused_loops(self): """Remove all unused loops. @@ -857,7 +948,7 @@ def cull_unused_loops(self): None """ - NotImplementedError + raise NotImplementedError def cull_unused_faces(self): """Remove all unused faces. @@ -867,7 +958,7 @@ def cull_unused_faces(self): None """ - NotImplementedError + raise NotImplementedError def contours(self, planes): """Generate contour lines by slicing the Brep shape with a series of planes. diff --git a/src/compas/data/samples/tubemesh.obj b/src/compas/data/samples/tubemesh.obj index 2d9e6f4a7d4..6c57c3b1231 100644 --- a/src/compas/data/samples/tubemesh.obj +++ b/src/compas/data/samples/tubemesh.obj @@ -1,210 +1,210 @@ # OBJ # COMPAS -# version: 1.4.0-8639de58 -# precision: 12f +# version: 2.0.0-alpha.2-4928ccb9 +# precision: 3f # V F E: 200 171 370 -# author: Tom Van Mele -v 24.849798896601 43.978228065655 4.894523914661 -v 22.565907640859 36.641759503121 5.203810489461 -v 29.855925178368 33.129556559162 3.826880821760 -v 9.733238847590 23.073526587110 3.822525587098 -v 10.494633088815 21.368078707032 5.493721105370 -v 11.612754343504 19.041444811040 6.371443224834 -v 12.798374622231 16.648979111140 6.405216773253 -v 13.808763405178 14.646399798423 5.617607605183 -v 14.449036451945 13.387479328539 4.103151938770 -v 14.603682327713 13.079530392262 2.079935106619 -v 14.307357152825 13.653928303902 0.000000000000 -v 20.964678588504 27.993756172420 3.645421442384 -v 19.839845739312 26.569123014021 3.500700549344 -v 18.474497510831 25.294209416885 3.495806831007 -v 16.955964523636 24.177205979729 3.631210177748 -v 15.365960585958 23.225519260696 3.906526982530 -v 13.744687752301 22.440761268077 4.315065759034 -v 9.935407884628 23.198355764247 -0.200424098988 -v 9.533966427369 23.735449932801 1.661431204020 -v 12.113742386280 21.821946875768 4.847307810774 -v 25.999523897871 31.948784843402 5.590376608402 -v 22.309241030139 34.373789787224 -0.200424098988 -v 31.267515591763 38.047459198961 -0.000000000000 -v 21.273025712477 41.769387718601 3.327746220198 -v 31.509160404976 48.446092761715 0.000000000000 -v 22.228662718238 31.245398983888 4.312190925580 -v 21.763652307838 29.559591301083 3.928560278285 -v 31.684964862277 44.917613041860 1.477054575371 -v 24.833259933479 47.696064582717 3.765970623526 -v 24.793028725877 38.270858351090 5.994598085685 -v 20.926432758131 42.970176092415 1.347186407564 -v 29.306608022596 42.438088397230 4.617908391856 -v 20.077754078195 28.768075693745 1.004607451905 -v 18.638685722653 27.836411437980 0.956293273540 -v 16.927613467236 27.066529415409 0.956529228107 -v 15.164223400154 26.369861248090 1.005295883915 -v 24.206816302110 25.688526629017 3.941228061444 -v 22.897646669505 23.919634523688 3.798376439602 -v 21.533063526843 22.212960114253 3.786587664694 -v 20.103958861689 20.571452944614 3.906981683986 -v 18.603544287703 18.997412315842 4.159603750066 -v 17.042174905138 17.488331828065 4.536556450203 -v 15.437889575681 16.039551152026 5.026382445557 -v 10.777968353176 24.310121727131 1.433044478338 -v 12.099132388144 24.968528989112 1.245808739724 -v 13.545366884067 25.668956123769 1.102351272516 -v 21.441383250694 31.395734304359 1.233736886552 -v 21.029336492622 29.948334523043 1.101182692323 -v 29.113243032406 30.862051893368 0.000000000000 -v 21.248195586615 36.754002993314 3.616789497340 -v 26.658163018060 29.409951141098 4.575073682020 -v 25.468813170183 27.516891793376 4.213076428441 -v 31.111940800653 48.742005476347 1.065947540365 -v 31.521953294056 37.884066749032 1.927179153228 -v 24.115020453559 32.540266646483 5.515105544141 -v 21.130713005502 45.205724844734 1.064831637329 -v 20.934338476016 38.402101737455 1.580335735923 -v 22.942989581296 45.243092437822 3.838628470112 -v 30.706205461370 44.808191205384 2.966253610856 -v 29.090630214311 35.633042136571 5.327254125576 -v 25.758882124743 24.659235383342 -0.000000000000 -v 24.383763752238 22.752813259036 -0.000000000000 -v 22.897833388762 20.937866967418 -0.000000000000 -v 21.315056181147 19.229300558513 -0.000000000000 -v 19.649514613977 17.641057135767 0.000000000000 -v 17.916158371160 16.179977806817 0.000000000000 -v 16.130325817905 14.849720543760 -0.000000000000 -v 21.407495483315 42.845171396532 -0.200424098988 -v 27.178581001318 42.275285227627 5.341243039537 -v 28.127477701340 28.703512067041 0.000000000000 -v 27.009378587245 26.642616955319 0.000000000000 -v 29.367071445839 30.796165006085 1.853409071417 -v 23.043957324817 48.585003676454 2.931520772993 -v 21.474149009209 33.040141517178 1.374408546625 -v 22.649658400601 40.207600523448 5.019144935714 -v 30.103796895632 48.849668394415 2.174049317095 -v 30.886580835049 37.824574340877 3.814721474836 -v 21.380184846419 44.716979081201 -0.200424098988 -v 21.846592744651 38.178469441306 -0.200424098988 -v 31.907956923014 42.839228703950 0.000000000000 -v 21.587697278834 44.641647189716 2.737926153485 -v 27.010646542421 35.969674913937 6.072630394674 -v 24.852245316269 42.104134244897 5.390226331294 -v 22.532430323461 34.824858306702 5.036305874194 -v 28.900048940801 30.970905032648 3.633909459436 -v 28.839568230377 46.689706535916 3.613977942783 -v 21.709364201372 47.411711813438 2.118789498831 -v 22.402275627576 32.577499114738 -0.200424098988 -v 21.992324355894 27.239132377894 4.318466013275 -v 20.858169539509 25.648820468977 4.153104072825 -v 19.547494952519 24.178195734390 4.144742214070 -v 18.098603292188 22.846542342549 4.294178557665 -v 16.549105231686 21.670775549692 4.601143545417 -v 14.931496953655 20.650302870482 5.057476805168 -v 13.275982310938 19.776684797992 5.651481278579 -v 30.689336686438 35.553052676629 -0.000000000000 -v 21.195828318909 40.179444587937 3.523824947428 -v 23.610095019142 30.702657082525 5.070655821044 -v 22.912408450917 28.929870057449 4.638949055628 -v 31.817635791138 42.735305034502 1.666112950374 -v 24.675179945206 36.341370760669 6.038516569581 -v 20.837134013346 41.638283823621 1.463978205012 -v 28.450806175082 50.700859914341 2.610866026352 -v 29.416259600401 40.184078527990 4.995797945599 -v 25.067215542524 25.104999187858 2.921506391034 -v 23.682926824045 23.284540034431 2.818007971611 -v 22.262916524665 21.517411845324 2.807919557736 -v 20.796428002014 19.799943008925 2.892198467031 -v 19.274556569945 18.128781497191 3.070971745652 -v 17.702084656256 16.502937204398 3.338230214719 -v 16.089929293725 14.922478645400 3.685214421124 -v 21.365716770059 34.976621079214 3.482241178445 -v 26.909838451148 46.332681706853 4.237457114238 -v 27.729321759066 28.930090169472 3.375332324940 -v 26.425551962768 26.982682336117 3.116767780574 -v 31.046524197242 35.406315196928 1.973169803683 -v 21.093975859081 36.616122369507 1.565771506071 -v 22.829112714356 43.601757290063 4.307278265741 -v 30.927762272615 42.593753893291 3.327318772648 -v 28.538909688634 33.453119667389 5.219806930997 -v 21.462382406209 41.564988094916 -0.200424098988 -v 31.785065504869 46.781266441901 0.000000000000 -v 26.707200018100 50.317071432216 3.123251545867 -v 27.244832614950 40.179352115371 5.746866718699 -v 23.027219447372 46.891838641419 3.362468403075 -v 24.843396011514 45.833538807468 4.333022993477 -v 22.600921688637 38.440328195720 5.190165768416 -v 30.519924587426 35.426597678477 3.891854797152 -v 31.152617451880 49.969317874077 0.000000000000 -v 22.092298802846 36.273606209239 -0.200424098988 -v 20.275535244299 28.541299214083 2.465449685566 -v 19.050864784068 27.343592761722 2.362204621476 -v 17.548876611080 26.312023588197 2.360522162211 -v 15.920322154870 25.418744205069 2.460566975343 -v 14.302682280840 24.639657658072 2.661955200986 -v 12.735360091304 23.978385784543 2.960249018509 -v 11.213799944872 23.450974066263 3.349193610072 -v 31.680799626743 40.513215713937 0.000000000000 -v 26.613848372958 33.924292113917 5.927363962003 -v 21.419751002127 43.246187893922 3.055282220232 -v 21.428129999829 31.506452339765 2.947448123229 -v 21.075360181862 29.932056053095 2.669427477934 -v 31.427566997135 46.906913452740 1.270655672168 -v 24.819575065213 49.591860470807 3.253652733152 -v 24.842271610432 40.197336241155 5.768124171302 -v 22.451942575942 33.013436694271 4.710950508594 -v 21.053308962145 44.132599301434 1.208285179116 -v 29.094099333829 44.606299710231 4.141905920082 -v 20.382254997149 28.638744172203 -0.200424098988 -v 18.680199333351 27.937422614043 -0.200424098988 -v 16.752995002609 27.373495994201 -0.200424098988 -v 14.873881315069 26.790769603231 -0.200424098988 -v 23.134309308649 26.430099004462 4.420709877017 -v 21.923904135142 24.729964030676 4.256310914985 -v 20.605384519625 23.117038861386 4.245341525561 -v 19.184989690351 21.605558486398 4.388845649038 -v 17.670721761794 20.207800239982 4.686717117020 -v 16.083611679384 18.921573158459 5.130349739089 -v 14.450529949154 17.738201544183 5.707327589799 -v 11.994950241140 25.162061058620 -0.200424098988 -v 10.910196290405 24.188117732460 -0.200424098988 -v 13.284674119126 26.052180464011 -0.200424098988 -v 22.215890507256 30.968875493041 -0.200424098988 -v 21.590539066918 29.631102014900 -0.200424098988 -v 29.967262039638 33.139675978556 0.000000000000 -v 21.189298908119 38.498018444737 3.625551578292 -v 25.194917654538 30.042476573027 5.159238704327 -v 24.230106543387 28.203381811403 4.736412674201 -v 21.707417324195 46.011529516780 2.413233790502 -v 30.804644795164 50.461875753643 0.881969879437 -v 31.771783665716 40.360925754669 1.820580271233 -v 24.459358291608 34.425548773622 5.870169559941 -v 21.071455125314 46.269918435224 0.934397533248 -v 20.842752031356 40.097946698180 1.544205731109 -v 28.604605669338 48.712969263139 3.086247598967 -v 30.407347266579 46.883222432386 2.569233686054 -v 29.363906688752 37.896078719103 5.242630558599 -v 25.603365939781 24.750274714738 1.500145836046 -v 24.197606066802 22.881715584057 1.448056317480 -v 22.734590915637 21.077784764373 1.442277747733 -v 21.212387511257 19.339430961230 1.483358051835 -v 19.630095336698 17.667778022831 1.571403887918 -v 17.994444385385 16.065244211105 1.703260675956 -v 16.315584668083 14.534827948049 1.874312139328 -v 21.474427892410 33.207890913530 3.239228692982 -v 21.408493544802 43.861717477543 -0.200424098988 -v 27.053797702525 44.324295918939 4.820627569922 -v 28.225171969724 28.689775922829 1.726101103610 -v 26.953204564261 26.682800164250 1.597649342462 -v 30.324684841742 33.027898087267 1.946303201519 -v 21.302077083488 34.805496014071 1.494294988407 -v 22.723368373539 41.930891679320 4.715732066446 -v 29.868192356769 50.738502217879 1.818509216428 -v 31.005514272688 40.241378609216 3.618538295368 -v 27.705594611050 31.383273602057 4.940591160572 -v 21.237200516404 45.513592198739 -0.200424098988 -v 21.620795026132 39.978863401663 -0.200424098988 -v 31.933558777437 44.927890865121 0.000000000000 -v 26.782409532645 48.322796871440 3.651672898232 -v 27.205054412315 38.066023822515 6.001805158237 +o Mesh 0 +v -3.226 6.251 1.528 +v -1.345 4.919 1.621 +v 0.333 6.674 1.208 +v 1.337 0.000 1.207 +v 1.894 0.059 1.708 +v 2.661 0.162 1.972 +v 3.454 0.279 1.982 +v 4.119 0.382 1.745 +v 4.537 0.448 1.291 +v 4.640 0.463 0.684 +v 4.448 0.432 0.060 +v 0.974 3.661 1.154 +v 1.276 3.208 1.110 +v 1.513 2.700 1.109 +v 1.691 2.163 1.149 +v 1.815 1.621 1.232 +v 1.889 1.086 1.355 +v 1.320 0.069 0.000 +v 1.129 0.005 0.559 +v 1.914 0.563 1.514 +v 0.312 5.464 1.737 +v -0.722 4.636 0.000 +v -0.939 7.532 0.060 +v -2.928 5.026 1.058 +v -3.884 8.565 0.060 +v 0.163 4.323 1.354 +v 0.601 4.034 1.239 +v -2.861 8.288 0.503 +v -4.289 6.591 1.190 +v -1.603 5.706 1.859 +v -3.303 5.038 0.464 +v -2.374 7.380 1.445 +v 0.671 3.479 0.362 +v 0.803 2.982 0.347 +v 0.864 2.423 0.347 +v 0.900 1.855 0.362 +v 1.932 4.372 1.242 +v 2.316 3.834 1.200 +v 2.676 3.287 1.196 +v 3.012 2.727 1.232 +v 3.322 2.153 1.308 +v 3.608 1.568 1.421 +v 3.872 0.976 1.568 +v 1.081 0.413 0.490 +v 1.015 0.851 0.434 +v 0.949 1.328 0.391 +v 0.048 4.112 0.430 +v 0.422 3.860 0.390 +v 0.911 6.251 0.060 +v -1.499 4.554 1.145 +v 1.098 5.416 1.433 +v 1.528 4.902 1.324 +v -4.005 8.479 0.380 +v -0.869 7.590 0.638 +v -0.031 4.981 1.715 +v -3.921 5.304 0.380 +v -1.998 4.617 0.534 +v -3.764 5.824 1.212 +v -2.920 7.999 0.950 +v -0.452 6.687 1.658 +v 2.370 4.719 0.060 +v 2.786 4.150 0.060 +v 3.166 3.558 0.060 +v 3.507 2.948 0.060 +v 3.806 2.326 0.060 +v 4.062 1.696 0.060 +v 4.276 1.063 0.060 +v -3.222 5.164 0.000 +v -2.525 6.758 1.663 +v 1.436 5.770 0.060 +v 1.920 5.260 0.060 +v 0.953 6.318 0.616 +v -4.708 6.163 0.940 +v -0.419 4.274 0.472 +v -2.355 5.274 1.566 +v -4.129 8.202 0.712 +v -0.911 7.403 1.205 +v -3.759 5.330 0.000 +v -1.850 4.856 0.000 +v -2.247 8.159 0.060 +v -3.718 5.382 0.882 +v -0.741 6.125 1.882 +v -2.692 6.078 1.677 +v -0.830 4.741 1.571 +v 0.860 6.201 1.150 +v -3.630 7.641 1.144 +v -4.497 5.673 0.696 +v -0.201 4.496 0.000 +v 1.285 3.884 1.356 +v 1.633 3.413 1.306 +v 1.931 2.903 1.304 +v 2.177 2.366 1.348 +v 2.369 1.815 1.440 +v 2.510 1.259 1.577 +v 2.606 0.705 1.756 +v -0.281 7.136 0.060 +v -2.481 4.856 1.117 +v 0.446 4.667 1.581 +v 0.887 4.303 1.452 +v -2.226 8.124 0.560 +v -1.064 5.493 1.872 +v -2.931 4.889 0.499 +v -4.811 7.902 0.843 +v -1.721 7.202 1.559 +v 2.179 4.563 0.937 +v 2.570 4.000 0.906 +v 2.942 3.431 0.903 +v 3.296 2.853 0.928 +v 3.632 2.264 0.981 +v 3.950 1.665 1.062 +v 4.252 1.058 1.166 +v -0.981 4.422 1.105 +v -3.707 7.057 1.331 +v 1.334 5.678 1.073 +v 1.769 5.125 0.995 +v -0.206 7.224 0.652 +v -1.474 4.497 0.530 +v -3.306 5.640 1.352 +v -2.268 7.857 1.058 +v 0.119 6.328 1.626 +v -2.852 5.061 0.000 +v -3.383 8.490 0.060 +v -4.863 7.369 0.997 +v -1.921 6.582 1.784 +v -4.227 6.001 1.069 +v -3.756 6.421 1.360 +v -1.855 5.096 1.617 +v -0.261 7.076 1.228 +v -4.352 8.605 0.060 +v -1.284 4.750 0.000 +v 0.754 3.515 0.800 +v 0.982 3.054 0.769 +v 1.137 2.530 0.768 +v 1.241 1.983 0.798 +v 1.313 1.449 0.859 +v 1.357 0.940 0.948 +v 1.366 0.457 1.065 +v -1.605 7.879 0.060 +v -0.194 5.822 1.838 +v -3.336 5.204 0.977 +v 0.015 4.119 0.944 +v 0.431 3.872 0.861 +v -3.452 8.399 0.441 +v -4.831 6.763 1.036 +v -2.148 5.898 1.791 +v -0.320 4.550 1.473 +v -3.622 5.182 0.423 +v -3.012 7.520 1.303 +v 0.736 3.554 0.000 +v 0.778 3.004 0.000 +v 0.761 2.401 0.000 +v 0.753 1.811 0.000 +v 1.621 4.135 1.386 +v 1.994 3.632 1.337 +v 2.332 3.106 1.334 +v 2.632 2.561 1.377 +v 2.890 1.999 1.466 +v 3.110 1.427 1.599 +v 3.296 0.851 1.772 +v 0.950 0.839 0.000 +v 1.128 0.439 0.000 +v 0.816 1.289 0.000 +v 0.241 4.293 0.000 +v 0.565 3.991 0.000 +v 0.340 6.706 0.060 +v -2.002 4.699 1.148 +v 0.782 5.058 1.608 +v 1.217 4.612 1.481 +v -4.098 5.543 0.784 +v -4.524 8.551 0.325 +v -1.553 7.891 0.606 +v -0.537 5.254 1.821 +v -4.231 5.385 0.340 +v -2.491 4.748 0.523 +v -4.229 7.761 0.986 +v -3.540 8.106 0.831 +v -1.073 6.975 1.633 +v 2.329 4.683 0.510 +v 2.732 4.109 0.495 +v 3.111 3.524 0.493 +v 3.466 2.929 0.505 +v 3.796 2.323 0.532 +v 4.102 1.707 0.571 +v 4.383 1.086 0.622 +v -0.466 4.289 1.032 +v -3.512 5.258 0.000 +v -3.121 6.912 1.506 +v 1.448 5.797 0.578 +v 1.903 5.248 0.539 +v 0.405 6.798 0.644 +v -0.938 4.388 0.508 +v -2.839 5.454 1.475 +v -4.690 8.310 0.606 +v -1.590 7.661 1.146 +v 0.632 5.898 1.542 +v -3.999 5.363 0.000 +v -2.385 4.959 0.000 +v -2.841 8.360 0.060 +v -4.287 7.205 1.156 +v -1.321 6.375 1.861 f 175 199 123 103 f 138 171 100 80 f 82 101 30 200 diff --git a/src/compas/datastructures/mesh/join.py b/src/compas/datastructures/mesh/join.py index 613d6d8ac24..b79369467b6 100644 --- a/src/compas/datastructures/mesh/join.py +++ b/src/compas/datastructures/mesh/join.py @@ -83,7 +83,8 @@ def meshes_join(meshes, cls=None): faces = [] for mesh in meshes: - key_index = {key: len(vertices) + i for i, key in enumerate(mesh.vertices())} + offset = len(vertices) + key_index = {key: offset + i for i, key in enumerate(mesh.vertices())} vertices += [mesh.vertex_coordinates(key) for key in mesh.vertices()] faces += [[key_index[key] for key in mesh.face_vertices(fkey)] for fkey in mesh.faces()] diff --git a/src/compas/geometry/shapes/box.py b/src/compas/geometry/shapes/box.py index d4d13360c70..40e0a3dfee9 100644 --- a/src/compas/geometry/shapes/box.py +++ b/src/compas/geometry/shapes/box.py @@ -26,12 +26,15 @@ class Box(Shape): ---------- xsize : float The size of the box in the box frame's x direction. - ysize : float + ysize : float, optional The size of the box in the box frame's y direction. - zsize : float + Defaults to the value of ``xsize``. + zsize : float, optional The size of the box in the box frame's z direction. - frame : :class:`~compas.geometry.Frame` + Defaults to the value of ``xsize``. + frame : :class:`~compas.geometry.Frame`, optional The frame of the box. + Defaults to ``Frame.worldXY()``. Attributes ---------- @@ -510,6 +513,46 @@ def from_diagonal(cls, diagonal): # """ + # ========================================================================== + # Conversions + # ========================================================================== + + def to_vertices_and_faces(self, triangulated=False): + """Returns a list of vertices and faces. + + Parameters + ---------- + triangulated: bool, optional + If True, triangulate the faces. + + Returns + ------- + list[list[float]], list[list[int]] + A list of vertex locations, and a list of faces, + with each face defined as a list of indices into the list of vertices. + + """ + if triangulated: + faces = [] + for a, b, c, d in self.faces: + faces.append([a, b, c]) + faces.append([a, c, d]) + else: + faces = self.faces + return self.vertices, faces + + def to_brep(self): + """Returns a BREP representation of the box. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_box(self) + # ========================================================================== # Transformations # ========================================================================== @@ -565,30 +608,6 @@ def scale(self, factor): # Methods # ========================================================================== - def to_vertices_and_faces(self, triangulated=False): - """Returns a list of vertices and faces. - - Parameters - ---------- - triangulated: bool, optional - If True, triangulate the faces. - - Returns - ------- - list[list[float]], list[list[int]] - A list of vertex locations, and a list of faces, - with each face defined as a list of indices into the list of vertices. - - """ - if triangulated: - faces = [] - for a, b, c, d in self.faces: - faces.append([a, b, c]) - faces.append([a, c, d]) - else: - faces = self.faces - return self.vertices, faces - def contains_point(self, point, tol=1e-6): """Verify if the box contains a given point. diff --git a/src/compas/geometry/shapes/capsule.py b/src/compas/geometry/shapes/capsule.py index 539076892c0..ec567ba9074 100644 --- a/src/compas/geometry/shapes/capsule.py +++ b/src/compas/geometry/shapes/capsule.py @@ -25,14 +25,14 @@ class Capsule(Shape): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional - The local coordinate system, or "frame", of the capsule. - Default is ``None``, in which case the world coordinate system is used. - radius : float, optional + radius : float The radius of the capsule. - height : float, optional + height : float The height of the capsule along the z-axis of the frame. Half of the capsule is above the XY plane of the frame, the other half below. + frame : :class:`~compas.geometry.Frame`, optional + The local coordinate system, or "frame", of the capsule. + Default is ``None``, in which case the world coordinate system is used. Attributes ---------- @@ -334,6 +334,18 @@ def to_vertices_and_faces(self, u=16, v=16, triangulated=False): return vertices, faces + def to_brep(self): + """Returns a BRep representation of the capsule. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_capsule(self) + # ============================================================================= # Transformations # ============================================================================= diff --git a/src/compas/geometry/shapes/cone.py b/src/compas/geometry/shapes/cone.py index 86ce8a0999e..80294afc65d 100644 --- a/src/compas/geometry/shapes/cone.py +++ b/src/compas/geometry/shapes/cone.py @@ -290,6 +290,18 @@ def to_vertices_and_faces(self, u=16, triangulated=False): return vertices, faces + def to_brep(self): + """Returns a BRep representation of the cone. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_cone(self) + # ========================================================================== # Transformations # ========================================================================== diff --git a/src/compas/geometry/shapes/cylinder.py b/src/compas/geometry/shapes/cylinder.py index 1f34887ea7e..fe462c78f1b 100644 --- a/src/compas/geometry/shapes/cylinder.py +++ b/src/compas/geometry/shapes/cylinder.py @@ -24,14 +24,14 @@ class Cylinder(Shape): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional - The local coordinate system, or "frame", of the cylinder. - Default is ``None``, in which case the world coordinate system is used. - radius : float, optional + radius : float The radius of the cylinder. - height : float, optional + height : float The height of the cylinder along the z-axis of the frame. Half of the cylinder is above the XY plane of the frame, the other half below. + frame : :class:`~compas.geometry.Frame`, optional + The local coordinate system, or "frame", of the cylinder. + Default is ``None``, in which case the world coordinate system is used. Attributes ---------- @@ -293,6 +293,18 @@ def to_vertices_and_faces(self, u=16, triangulated=False): return vertices, faces + def to_brep(self): + """Returns a BRep representation of the cylinder. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_cylinder(self) + # ============================================================================= # Transformations # ============================================================================= diff --git a/src/compas/geometry/shapes/sphere.py b/src/compas/geometry/shapes/sphere.py index 42b1827b3ea..5f202ac90b1 100644 --- a/src/compas/geometry/shapes/sphere.py +++ b/src/compas/geometry/shapes/sphere.py @@ -18,11 +18,14 @@ class Sphere(Shape): Parameters ---------- + radius: float + The radius of the sphere. frame: :class:`~compas.geometry.Frame`, optional The local coordinates system, or "frame", of the sphere. Default is ``None``, in which case the sphere is constructed in world coordinates. - radius: float, optional - The radius of the sphere. + point: :class:`~compas.geometry.Point`, optional + The center of the sphere. + When provided, this point overwrites the location of the origin of the local coordinate system. Attributes ---------- @@ -69,7 +72,7 @@ class Sphere(Shape): "required": ["radius", "frame"], } - def __init__(self, radius, point=None, frame=None, **kwargs): + def __init__(self, radius, frame=None, point=None, **kwargs): super(Sphere, self).__init__(frame=frame, **kwargs) self._radius = 1.0 self.radius = radius @@ -253,6 +256,18 @@ def to_vertices_and_faces(self, u=16, v=16, triangulated=False): return vertices, faces + def to_brep(self): + """Returns a BRep representation of the sphere. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_sphere(self) + # ============================================================================= # Transformations # ============================================================================= diff --git a/src/compas/geometry/shapes/torus.py b/src/compas/geometry/shapes/torus.py index bd869272063..ebfcc5bf299 100644 --- a/src/compas/geometry/shapes/torus.py +++ b/src/compas/geometry/shapes/torus.py @@ -19,13 +19,13 @@ class Torus(Shape): Parameters ---------- - frame : :class:`~compas.geometry.Frame`, optional - The local coordinate system of the torus. - Default is ``None``, in which case the torus is constructed in the radius_axis: float, optional The radius of the axis. radius_pipe: float, optional The radius of the pipe. + frame : :class:`~compas.geometry.Frame`, optional + The local coordinate system of the torus. + Default is ``None``, in which case the torus is constructed in the world XY plane. Attributes ---------- @@ -81,7 +81,7 @@ def __init__(self, radius_axis, radius_pipe, frame=None, **kwargs): self.radius_pipe = radius_pipe # ========================================================================== - # data + # Data # ========================================================================== @property @@ -101,7 +101,7 @@ def from_data(cls, data): ) # ========================================================================== - # properties + # Properties # ========================================================================== @property @@ -145,7 +145,7 @@ def volume(self): return (pi * self.radius_pipe**2) * (2 * pi * self.radius_axis) # ========================================================================== - # customisation + # Customisation # ========================================================================== def __repr__(self): @@ -180,7 +180,7 @@ def __iter__(self): return iter([self.frame, self.radius_axis, self.radius_pipe]) # ========================================================================== - # constructors + # Constructors # ========================================================================== @classmethod @@ -212,7 +212,7 @@ def from_plane_and_radii(cls, plane, radius_axis, radius_pipe): return cls(plane=plane, radius_axis=radius_axis, radius_pipe=radius_pipe) # ========================================================================== - # methods + # Conversions # ========================================================================== def to_vertices_and_faces(self, u=16, v=16, triangulated=False): @@ -281,6 +281,22 @@ def to_vertices_and_faces(self, u=16, v=16, triangulated=False): return vertices, faces + def to_brep(self): + """Returns a BRep representation of the torus. + + Returns + ------- + :class:`compas.brep.Brep` + + """ + from compas.brep import Brep + + return Brep.from_torus(self) + + # ========================================================================== + # Transformations + # ========================================================================== + def transform(self, transformation): """Transform the torus. diff --git a/src/compas/geometry/surfaces/surface.py b/src/compas/geometry/surfaces/surface.py index 11b192cc5f9..dad1e20c3bd 100644 --- a/src/compas/geometry/surfaces/surface.py +++ b/src/compas/geometry/surfaces/surface.py @@ -247,7 +247,10 @@ def to_vertices_and_faces(self, nu=16, nv=16, du=None, dv=None): vertices = [ self.point_at(i, j) - for i, j in product(linspace(domain_u[0], domain_u[1], nu + 1), linspace(domain_v[0], domain_v[1], nv + 1)) + for i, j in product( + linspace(domain_u[0], domain_u[1], nu + 1), + linspace(domain_v[0], domain_v[1], nv + 1), + ) ] faces = [ [ @@ -431,7 +434,7 @@ def transform(self, T): # Methods # ============================================================================== - def u_space(self, n=10): + def space_u(self, n=10): """Compute evenly spaced parameters over the surface domain in the U direction. Parameters @@ -447,7 +450,7 @@ def u_space(self, n=10): umin, umax = self.domain_u return linspace(umin, umax, n) - def v_space(self, n=10): + def space_v(self, n=10): """Compute evenly spaced parameters over the surface domain in the V direction. Parameters @@ -463,7 +466,7 @@ def v_space(self, n=10): vmin, vmax = self.domain_v return linspace(vmin, vmax, n) - def u_isocurve(self, u): + def isocurve_u(self, u): """Compute the isoparametric curve at parameter u. Parameters @@ -477,7 +480,7 @@ def u_isocurve(self, u): """ raise NotImplementedError - def v_isocurve(self, v): + def isocurve_v(self, v): """Compute the isoparametric curve at parameter v. Parameters @@ -512,7 +515,7 @@ def pointgrid(self, nu=10, nv=10): The size of the grid in the V direction. """ - return [self.point_at(i, j) for i, j in product(self.u_space(nu), self.v_space(nv))] + return [self.point_at(i, j) for i, j in product(self.space_u(nu), self.space_v(nv))] def point_at(self, u, v): """Compute a point on the surface.