Closed agviegas closed 3 years ago
Some context about this topic:
Clipping Representation
is the representation based exclusively on the use of boolean results of clipped solids, so that:
half space solid
.The commonest use case for this kind of representation are IfcWall
instances. The wall body
can be cut out (clipped) at the bottom or top (e.g. for walls in rooms with sloped ceilings). The only restriction is that the cutting element has to be a plane. The following picture shows examples of valid clipped walls.
The following conditions are fullfilled in any IFC:
IfcArbitraryProfileDef
and IfcRelConnectsPathElement
instances. IfcOpeningElement
instances.Finally, there are two types of cutting planes: unlimited and bounded.
IfcHalfSpaceSolid
and IfcBoxedHalfSpace
can be used. IfcPolygonalBoundedHalfSpace
can be used.Below you can see a simple example of a wall with this representation:
#1=IFCWALLSTANDARDCASE('abcdefghijklmnopqrst01', #2, $, $, $, #3, #4, $);
#3=IFCLOCALPLACEMENT($, #10);
#4=IFCPRODUCTDEFINITIONSHAPE($, $, (#11, #13));
#10=IFCAXIS2PLACEMENT3D(#16, $, $);
#16=IFCCARTESIANPOINT((2.0E+00, 1.0E+00, 0.0E+00));
#12=IFCGEOMETRICREPRESENTATIONCONTEXT($, $, 3, $, #14, $);
#14=IFCAXIS2PLACEMENT3D(#15, $, $);
#15=IFCCARTESIANPOINT((0.0E+00, 0.0E+00, 0.0E+00));
/* shape representation of the wall axis */
#11=IFCSHAPEREPRESENTATION(#12, 'Axis', 'Curve2D', (#18));
#18=IFCTRIMMEDCURVE(#19,(#20),(#21),.T.,.CARTESIAN.);
#19=IFCLINE(#30, #31);
#30=IFCCARTESIANPOINT((0.0E+00, 0.0E+00));
#31=IFCVECTOR(#32,2.8E+00);
#32=IFCDIRECTION((1.0E+00, 0.0E+00));
#20=IFCCARTESIANPOINT((0.0E+00, 0.0E+00));
#21=IFCCARTESIANPOINT((2.80E+00, 0.0E+00));
/* shape representation of the clipped body */
#13=IFCSHAPEREPRESENTATION(#12, 'Body', 'Clipping', (#50));
#50=IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE., #22, #51);
/* geometric representation of the extruded solid */
#22=IFCEXTRUDEDAREASOLID(#23, #26, #29, 2.80E+00);
#26=IFCAXIS2PLACEMENT3D(#28, $, $);
#28=IFCCARTESIANPOINT((0.0E+00, 0.0E+00, 0.0E+00));
#29=IFCDIRECTION((0.0E+00, 0.0E+00, 1.0E+00));
#23=IFCARBITRARYCLOSEDPROFILEDEF(.AREA., $, #40);
#40=IFCPOLYLINE((#41,#42,#43,#44,#41));
#41=IFCCARTESIANPOINT((0.0E+00, 1.0E-01));
#42=IFCCARTESIANPOINT((2.8E+00, 1.0E-01));
#43=IFCCARTESIANPOINT((2.8E+00, -1.0E-01));
#44=IFCCARTESIANPOINT((0.0E+00, -1.0E-01));
/* geometric representation of the clipping plane */
#51=IFCHALFSPACESOLID(#52, .F.);
#52=IFCPLANE(#53);
#53=IFCAXIS2PLACEMENT3D(#54, #55, #56);
#54=IFCCARTESIANPOINT((0.0E+00, 0.0E+00, 2.0E+00));
#55=IFCDIRECTION((0.0E+00, -0.7070106E+00, 0.7070106E+00));
#56=IFCDIRECTION((1.0E+00, 0.0E+00, 0.0E+00));
Here are some notes from what I've learned so far:
@agviegas let me know if this sounds sensible. I'm going to start working on a solution based on these criteria.
Everything sounds good to me. I have implemented the basic structure for this; make sure to pull the last changes.
In the ifc-map.js there is now an entry that will handle any geometry of type Clipping
to ifc-clipping.js, which right know is only logging the geometry that receives. If we followed the structure of the rest of the code, there would be two tasks:
I have executed the last implementation with the first example of the examples folder, which is a wall with two cuts, and this is what is logged in the console:
There are two clipping operations that are made through two IfcPlane
instances. I think that the sequence of actions is:
IfcOpeningElement
instances from the walls).Also, I would consider the following:
getMappedGeometry
. You can see an example of this for the mapped representations. This function will create the wall (with no boolean operations) and locate it in it`s correct position in space. Position
property to define the position of the clipping volumes in space. I have solved this in local-transform-tracker.js and ifc-local-transform-applier.js. You can see examples of their use in other geometries such as swept solids, with the functions trackLocalTransform
and applyTransformsTo
. Once you have created the clipping volumes (in the center of the scene, which is what THREE.js does by default), these functions will place the object in the correct position. Bear in mind that all objects need to be located in space before you can apply the boolean operations.Thanks, that's very helpful! I'll get started on the implementation.
Great! I am excited to see what you do; this is an important milestone in the project.
If you find yourself struggling with the implementation, don't hesitate to submit a draft pull request with what you have so I can help. 🙂
Once I push my last changes, this will be solved. There might be cases that are not implemented yet, but I think this is a great first step forward in this field. Maybe we can do this in future Issues / PRs.
By the way, I will be showing this advances in twitter, in case you want to join / show what you have done here. 🙂
IFC can generate geometries in various forms. One of them is Clipping Operations, ergo, boolean operations. Generally, the only boolean operation included in IFC is difference. A common case for this are the walls that are cut by slabs. In this case, the wall is represented as a whole wall, and then the subtraction is applied. The tasks for this issue are:
[x] Understanding how clipping is expressed in IFC.
[x] Understanding how clipping could be applied in Three.js. This is already implemented for extracting the OpeningElements from the walls geometry by difference boolean operations. See file boolean-operator.js.
[x] Adding the logic to ifc-clipping.js to extract the necessary information.
[x] Adding the logic to three-clipping.js file that takes this information and generates the geometry.
[x] Testing different use cases.
The testing files provided for this issue can be found here.