ThatOpen / web-ifc-viewer

Graphics engine and toolkit for client applications.
MIT License
945 stars 234 forks source link

Implementation of Clipping Representation #12

Closed agviegas closed 3 years ago

agviegas commented 3 years ago

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:

The testing files provided for this issue can be found here.

agviegas commented 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:

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.

image

The following conditions are fullfilled in any IFC:

Finally, there are two types of cutting planes: unlimited and bounded.

Below you can see a simple example of a wall with this representation:

image

 #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));
apemann commented 3 years ago

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.

agviegas commented 3 years ago

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:

Captura

There are two clipping operations that are made through two IfcPlane instances. I think that the sequence of actions is:

  1. All the geometry instances are created.
  2. The boolean operations are applied using the same library as here (this is beeing used for extracting the IfcOpeningElement instances from the walls).
  3. All the geometry (except for the final boolean result) is deleted.

Also, I would consider the following:

apemann commented 3 years ago

Thanks, that's very helpful! I'll get started on the implementation.

agviegas commented 3 years ago

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. 🙂

agviegas commented 3 years ago

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. 🙂

image image image