Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSG Module 2.0 #206

Closed
wants to merge 17 commits into from
Closed

CSG Module 2.0 #206

wants to merge 17 commits into from

Conversation

joeng03
Copy link
Contributor

@joeng03 joeng03 commented Apr 12, 2023

Description

Objectives:

Statement:
Fix the current issue of incorrect display of colour after boolean operations (union, subtract, intersect) on primitive shapes. Currently, the colours of the initial Shapes are not preserved in the resulting Shape, instead a default colour (grey) is used.

Approach:
This can be achieved through patching the @jscad/modeling package. We have used patch-package to ensure that our patch is applied seamlessly every time a new installation (i.e. every run of yarn install) is performed. By tracing the code and referring to Version 1 of JSCAD and CSG.js, we found out that the colors are not preserved due to the single polygons which make up a solid not storing the color. The boolean operations are carried out through a Binary Space Partitioning (BSP) tree data structure, in which the color of polygons are not preserved during when they are split. We modified several methods to ensure that the colors of individual Shapes are stored in the polygons after boolean operations. Since retesellation combines coplanar planes even when they have different colors, we prefer to remove the retesellation functionality for this stage of development.

Statement:
Introduce hierarchy of Shapes by adding Groups. Groups can consist of Shapes or Groups. When transformations are applied to Groups, all objects in the Group undergo the transformation.

Approach:
A new class, Group was added to the utilities.ts file. Group takes in a List of Group|Shape, and contains an attribute, transforms, which stores the transformation matrix of the Group.
Both the Shape and Group classes now implement the Entity interface, which contains the transformation methods.

Statement:
Delay transformations on objects until the object is to be rendered to increase speed during modelling. Combine transformations when performing the final transformation, so that each individual Shape only undergoes one transformation operation. This feature has to integrate with Groups.

Approach:
Both the Shape and Group classes now implement the Entity interface, which contains the transformation methods. Due to considerations for efficiency, Groups actually shallow copies all its children under the hood during transformations, while creating an impression of immutability (new object created) on the client side. Deep copying is done lazily (delayed until rendering stage). During the rendering stage, the transformations are passed down the tree structure of the Group.

Statement:
Enforce the immutable and side-effect-free functional programming experience of the CSG module. This includes enforcing the immutability of shapes, the creation of a new object for every operation, and the removal of statefulness during rendering.

Approach:
Every primitive is now exported as a function which takes in a hex string as color, and further mutation of colors of a Shape throughout its lifecycle are now disallowed. Furthermore, the store() function is removed, and its functionality is now achieved by passing either a Group or a Shape into the render() function in the final lines of the code.

Statement:
Add a STL serializer to serialize CSG shapes into .stl files, for the purpose of 3D printing.

Approach:
Add another dependency, @jscad/stl-serializer, which exports a method, serialize, to convert a JSCAD shape into an .stl file.

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.

  • Test A
  • Test B

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, taking a quick glance at the PRs and noticed that you may have accidentally committed some files as below, could you check again?

Thanks for the hard work!

patches/@jscad+modeling+2.11.0.patch Outdated Show resolved Hide resolved
.idea/.gitignore Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the files in the .idea folder may have been mistakenly committed into your branch. Do you mind deleting them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just removed!

@martin-henz
Copy link
Member

What's the status of this PR? Merge?

@joeng03
Copy link
Contributor Author

joeng03 commented Apr 28, 2023

It is still under development as we still have several bugs to resolve. Now that finals has ended, I will work on it with Chenbo.

@RichDom2185
Copy link
Member

It is still under development as we still have several bugs to resolve. Now that finals has ended, I will work on it with Chenbo.

Ok, in that case, let us mark it as draft first. Feel free to mark the PR as ready when the bugs have been resolved!

@RichDom2185 RichDom2185 marked this pull request as draft May 8, 2023 13:56
@joeng03 joeng03 force-pushed the csg branch 2 times, most recently from dc81e48 to 130729b Compare May 17, 2023 15:36
…on on transformed Boolean operation product' bug
@joeng03
Copy link
Contributor Author

joeng03 commented May 20, 2023

Hi @RichDom2185, we have resolved the bugs and are ready to merge!

@RichDom2185 RichDom2185 marked this pull request as ready for review May 20, 2023 23:31
@RichDom2185
Copy link
Member

Hi @RichDom2185, we have resolved the bugs and are ready to merge!

Do you have some demo/example code to play around with this module?

Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there any reason functions like scale_(x|y|z), flip_(x|y|z), transform_(x|y|z), shape_center, area, volume, etc. were removed from the list of exports?

Comment on lines 46 to 50
function colorize(shape: Shape, hex: string) {
let color: Color = hexToColor(hex);
let coloredSolid: Solid = _colorize(color, shape.solid);
return new Shape(coloredSolid);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like the workflow warning says, this function does not seem to be used anywhere?

Copy link
Contributor Author

@joeng03 joeng03 May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there any reason functions like scale_(x|y|z), flip_(x|y|z), transform_(x|y|z), shape_center, area, volume, etc. were removed from the list of exports?

It was a change requested by Prof Low to make the set of exported functions less redundant

Just like the workflow warning says, this function does not seem to be used anywhere?

Thanks for reminding :) Going to remove it in the latest commit

* ranging from 0 to infinity.
* For example scaling the shape by 1 in x, y and z direction results in
* Scales the shape in the x, y and z direction with the specified factor.
* Factors must be non-zero.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why must factors be non-zero? Strictly speaking, shouldn't it be technically possible to scale an entity by a factor of 0 (making it infinitesimally small)?

If it is to get around an error, I don't think this is the best way to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSCAD code (node_modules@jscad\modeling\src\operations\transforms\scale.js) currently does not even allow negative values and will throw an error if factors are <=0. We decided to add a <=0 check in function.ts to avoid revealing the JSCAD implementation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like we are artificially enforcing that factors are positive simply to get around this limitation/error of the JSCAD library. It's not about revealing implementation; what I meant was more of a question of "should we support scaling by non-positive factors?".

If we can define scaling by a negative number to be _"flip in the corresponding axes that are scaled by a negative factor, and then scale by the absolute value of the factors" then why can't we just implement it that way in the code? Artificially capping it to >= 0 just because it will through an error otherwise does not seem like the best thing to do. Is there any reason (perhaps pedagogical/etc.) that it was not done this way?

Likewise, for scaling with a 0 factor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it is possible to support negative scaling by patching the JSCAD code, Prof has said that he does not support the inclusion of such a functionality.

"I don't support the inclusion of negative scaling. It is not often used in 3D modelling. Would rather have a separate flip function to do that. Since all the primitive shapes we provide have some symmetry such that flipping can be achieved with rotation, a separate flip function or negative scaling is not necessary."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay sure, if that's the reason then I guess that's fine. Thanks for the clarification!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly is the command you are using to merge master into this branch? Your force pushes seem to be causing weird things in the GitHub PR list of changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to troubleshoot. Essentially, the module is done right? All that's left is to merge master?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, all that's left is to merge master

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a new branch with the contents of this PR just before your most recent force-pushed? (This one below)

image

What was the rationale of the force-push btw?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, was able to dig the commit out of GitHub's servers. See #213.

@joeng03
Copy link
Contributor Author

joeng03 commented May 25, 2023

Hi @RichDom2185, we have resolved the bugs and are ready to merge!

Do you have some demo/example code to play around with this module?

Its in samples.md, do let me know if you run into any issues with the sample code!

@RichDom2185 RichDom2185 mentioned this pull request May 29, 2023
@RichDom2185
Copy link
Member

Superseded by #213.

@joeng03
Copy link
Contributor Author

joeng03 commented May 29, 2023

Hi @RichDom2185 , thanks for solving the issues of this PR!
As I am not that experienced in Git yet, I might have messed up the commit history by force-pushing. Could you explain what caused the syntax error issue after merging with the master branch, and how did you resolve it? Thanks!

@RichDom2185
Copy link
Member

Hi @RichDom2185 , thanks for solving the issues of this PR! As I am not that experienced in Git yet, I might have messed up the commit history by force-pushing. Could you explain what caused the syntax error issue after merging with the master branch, and how did you resolve it? Thanks!

Hi, refer to my comment here: #206 (comment). I honestly did not know what command you used, so I can't comment on that (yet). But what I did was:

  1. go back to an earlier version of this branch (thank goodness for the PR, cause it kept track of the history of force-pushes)
  2. found that earlier commit on GitHub
  3. created a new branch from that earlier commit
  4. did an interactive rebase of that newly created branch on top of the latest master, ignoring conflicts on auto-generated files (e.g. yarn.lock, since they can be easily recreated later)
  5. cherry-picked all remaining commits from the latest version
  6. re-ran yarn install to update the yarn.lock without worrying about merge conflicts
  7. re-formatted all files to fix their lint issues
  8. manually resolved some compile errors from incorrect merge conflict resolutions

Of course, this is harder than it sounds. In reality, the first 2 interactive rebase attempts were unsuccessful because of an incorrect ordering of commits (this is what happens when you try to rebase after you have merged some branches – generally, either use merge commits all the way or rebase all the way to make your life easier, don't use/mix both methods). The main issues were:

  • One of you kept committing the .idea files from your editor (WebStorm?), this should not be there in the first place to begin with, not only did it cause merge conflicts, it messes up other people's editors as well as the config files kept getting overwritten
  • One of you has a different linter/formatter setup, that does not follow/respect the rules set for this codebase. For example, the files were constantly reformatted to use double quotes " instead of single quotes ' for strings. In your commits, your formatter kept changing so many lines (not just the quotes, but other rules such as indentation, line length, etc, were all overridden), that it resulted in numerous merge conflicts in every step. Please ensure that your linter is properly set up so that it respects the rules set for the codebase, and also ensure your files are properly formatted before committing them. You should not wait until the very last commit to run yarn lint --fix to reformat all your files at once.

The above comment was mainly about the merge conflicts that I encountered while rebasing, and focused on how we can prevent conflicts (by configuring our editors properly).

In terms of how I resolved it, it is no other than just a simple rebase on top of master (essentially merging master into the branch), which is why I suspect you probably used the command wrongly, hence the above linked comment.

@RichDom2185
Copy link
Member

Based on the commit titles and hashes of this (and my experience debugging PRs), I strongly suspect somewhere along the way, the following happened:

  • you tried to merge with master, but
  • encountered merge conflicts, so
  • you wanted to cancel the merge, and so
  • undid all the merge changes (cleaning up your working directory), but
  • did not do git merge --abort for some reason, and hence
  • subsequently, when you wanted to commit a new change (bugfix/etc.),
  • your next commit, which is supposed to be a feature commit,
  • is created as a merge commit by git instead (because git still thinks you are merging), thus
  • as a result, git thinks that
    • you have merged with master at that point in time,
    • but decided the right course of action was to ignore all the new changes from master,
    • and simply keep your changes
  • thus the next time you tried to pull master again,
  • you think you are N commits behind master,
  • but git thinks you are only N-some number commits behind master (or even up to date), and
  • if you try to rebase now, not only will that not help (because git thinks you are up to date), but
  • you will also lose some of your actual, feature/fix/changes, because rebasing removes merge commits, and because you did not abort the merge earlier, git mistakenly marked what should be your normal commit as a merge commit

Cloud7050 added a commit to Cloud7050/modules that referenced this pull request Sep 11, 2023
martin-henz pushed a commit that referenced this pull request Sep 12, 2023
* feat(src): Extract & update CSG's CSS constants

* chore(csg): Remove V1 comments referencing fork issues

* feat(csg): Migrate to BlueprintJS Tooltips

* devfeat(csg): Update samples

* devfeat(curve): Add samples

* docs(curve): Update animation function docs

* ref(csg): Remove default colour

The addition of operation colour preservation and removal of the store/render pattern means that all Shapes now require an explicit colour. Changing the default colour of the wrapped renderer no longer has a visible effect.

* fix(build): Fix `build modules` building no tabs

Revise/clarify the logic of retrieveBundlesAndTabs() and update tests/comment.

* feat(): Enhance & make curve canvases consistent

* feat(csg): Replace hint dots with colons

* ref(csg): Use real js-slang lists

* devfeat(csg): Update colours sample

* devfeat(csg): Add primitives sample

* chore(pkg): Lock modeling version for patch file

* ref(build): Reorder config to match

Left over from tests with explicit tsconfig path when troubleshooting
build errors

* ref(csg): Rename to Operable, no List, move/del funcs

* fix(csg): Fix primitive sample trailing comma

* devfeat(csg): Add Prof's Sierpinski fractal

* FEAT(csg): Overhaul functions, documentation

* devfeat(csg): Update sample import names

* ref(csg): Reorder sample functions

* devfeat(csg): Add rotation sample

* devfeat(csg): Add summary snowglobe example as sample

* docs(csg): Plural categories, bulleted list, tweaks

* ref(csg): Refactor operables

Rename params, non-deep children copy for new Group

* feat(csg): Improve error feedback for pitfalls

* fix(csg): Implement proper ungroup

* feat(csg): Improve error feedback for pitfalls

* feat(csg): Update sample utility funcs

* feat(csg): Update sierpinski sample for new primitive

* fix(rune): Fix low resolution heart

* docs(csg): Link to GitHub samples in summary

* feat(csg): Update sierpinski sample

* feat(csg): Readd custom default colour due to bug #227

* ref(build): Remove leftover from troubleshooting

* docs(csg): Tweak pyramid dimensions description

* feat(sound): Throw error on invalid sound durations

Closes #110

* chore(pkg): Remove unused lodash

* feat(curve): Add Source version to canvases sample

* feat(tabs): Remove enforced spacing of MultiItemDisplay

* ref(csg): Default colour back in constants

* fix(csg): Disallow negative scaling, update docs instead

Based on #206 (comment).

* ref(csg): Rename RGB components to values

They were called components when the params were clamped between 0-1.
Now more fitting to call them values when 0-255.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants