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

feat(geometry): Adding Geometry Objects #3

Merged
merged 59 commits into from
May 28, 2019
Merged

feat(geometry): Adding Geometry Objects #3

merged 59 commits into from
May 28, 2019

Conversation

chriswmackey
Copy link
Member

You can see that this is a fairly large PR with ~5k lines of pythonic new code and docstrings. It gives us more than half of the things originally on the checklist for this library as you can see on the updated Readme page on my fork

If you want to get an initial sense of the capabilities, I recommend browsing the Surface3D class since many of the other classes in the library are in service of this one and this is also the one that I have been imaging would describe honeybee surfaces, essentially allowing us to move/transform them, generate glazing based on a ratio from them, generate analysis grids from them, etc.

The main reason why this is a draft PR is that I have been doing most of the testing of the library with the help of Rhino since it is much easier to generate a lot of cases and visually evaluate them there. So, while I am confident that 80% of the code works well from these tests, this means that I don't have any pure Python tests for CI and there are probably some bugs in the parts that have not been tested with Rhino. So, the next step for me is writing these tests.

In the meantime, I could definitely use feedback on the code and especially the class names and organization of the library. The organization seems very clear to me but I have a feeling this is because I have been in the zone working on it the last week.

... there are just a couple of last things that I need to impelment on Mesh2D.
I still need to write some tests for them but all fundamental 2D objects are now complete.
I have been doing tests in Rhino just because it is quicker so I am fairly certain that 80% of the code is working.  I will begin writing pure Python tests and (likely) fixing bugs soon.
@chriswmackey chriswmackey added enhancement New feature or request critical Features/fixes that are critical to continued development new development For issues that require new code labels Mar 31, 2019
@mostaphaRoudsari
Copy link
Member

Thanks @chriswmackey! This is a long one. Let's see what will be the best strategy to review it. A number of quick notes after checking a number of files.

  1. Is Surface3D also a planar surface? If that is the case should we call it a Face?
  2. I would say it's better to remove Ladybug from __repr__ methods. We can just call then Surface, Mesh and so on instead of Ladybug Surface, ...
  3. Since the geometry instances will easily be used tens of thousands of time I think we should use __slots__ for all of them.
  4. As you are writing tests it would be great if we can also use them as sample codes to show case how this library should be used.

@chriswmackey
Copy link
Member Author

@mostaphaRoudsari ,
Thank you for the quick comments and I think we definitely want to take our time on reviewing this one. Given our busy schedule this month, I am not planning on being ready to merge this in until May but I think that I can work on writing tests as you review the code.

To respond to your comments:

  1. Are you not concerned about the confusion that this could create by calling both mesh faces and objects representing polygonal surfaces by the name Faces? I guess I should have asked why you decided to call this object within the pollination API a Face instead of a Surface and what you think each of these terms means. Actually, after reading through the Wikipedia definiteion of surface, I think I get what you mean. Are you thinking that surfaces can be non-planar while faces are always planar? If so, I can get behind this name change. I am also realizing that there is not much risk of confusion with mesh faces here since there really isn't a mesh face class in this library (I just use tuples to store the indices of each face).

  2. I originally had it the way that you suggested but then I started doing tests in Rhino, where I was working with both Rhino geometries and Ladybug geometries, and I realized how easy it is to get these two confused with one another. So I figured, if I have moments of mistaking a Rhino Point3D from a Ladybug Point3D, other people working with Ladybug API in Grasshopper are definitely going to have moments like this. Then it crossed my mind that, if we ever have a situation where the Ladybug geometry is output from a component (perhaps for speed), it would create a lot of confusion for users to see an output just called Mesh (vertices 4, faces 1) and then not be able to preview the mesh in the Rhino scene or treat it like a Rhino Mesh. So I added in the Ladybug in front of the __repr__ names for all of the geometries to help me (and presumably others) more easily distinguish between them and the Rhino objects. So my question to you would be, if not adding Ladybug in front of the __repr__ name, what should we do to help users distinguish these objects from their counterparts within CAD SDKs?

  3. I am already using __slots__ on all of the small objects that get called thousands of times (points, vectors, line segments, rays) and I have already witnessed what a difference it makes in my tests. The reason why __slots__ is not being used on the Polygon or Surface class is that it is set up such that most of the properties are simply None upon creation of the object in order to help save memory and calculation time (things like area, perimeter, is_convex, triangulated_mesh are all None to start off with). If these properties are needed, they are calculated upon request and then cached on the object such that they don't need to be recalculated in future calls to the property. The thing is that this memory and computation saving feature conflicts with how __slots__ works because I end up re-defining the properties from None to the actual property when they are requested. There is a way around this in that I could go back to using __slots__ and simply not define the properties as None (using hasattr on the properties instead of asking if the property is None). But this type of call would be made hundreds of times for some objects and I thought calling the hasattr on the properties would take longer than asking if the property is None (admittedly, I am not sure if this is true). Also, using hasattr would prevent me from using some tricks I added in like, for mesh grids, I store the face area as a single value to save memory (since all mesh faces have the same area).

  4. Will definitely do!

@chriswmackey
Copy link
Member Author

@mostaphaRoudsari ,
I am just letting you know that, after our discussions yesterday, I have addressed all of the initial comments that you brought up.

I realized that one of the methods that I added previously did not do what I thought it did so I have removed it.  I also added a method to automatically create a single closed polygon from a shape with a hole.  I ran it through several tests in Rhino and it seems to be working well.  There aren't any cases I can think of that will not work with the general calculation method and I think I can get it to work for shapes with multiple hole just by having it recurse.
... and everything seems to be working well!
@chriswmackey chriswmackey marked this pull request as ready for review May 1, 2019 19:59
This should give us everything that we need to build energy model geometry in the way that we do now with honeybee legacy.  There are just a few small methods left that I want to implement on the Polyface3D object to make it consistent with the other objects.
@mostaphaRoudsari mostaphaRoudsari self-requested a review May 21, 2019 15:59
Copy link
Member

@mostaphaRoudsari mostaphaRoudsari left a comment

Choose a reason for hiding this comment

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

Added a number of comments on the first couple of files that I get to check. Will add more comments once I get a chance.

ladybug_geometry/_mesh.py Show resolved Hide resolved
ladybug_geometry/_mesh.py Outdated Show resolved Hide resolved
ladybug_geometry/_mesh.py Outdated Show resolved Hide resolved
ladybug_geometry/_mesh.py Show resolved Hide resolved
ladybug_geometry/_mesh.py Show resolved Hide resolved
ladybug_geometry/geometry2d/line.py Outdated Show resolved Hide resolved
ladybug_geometry/geometry2d/line.py Show resolved Hide resolved
ladybug_geometry/geometry2d/line.py Show resolved Hide resolved
ladybug_geometry/geometry2d/mesh.py Outdated Show resolved Hide resolved
ladybug_geometry/geometry2d/pointvector.py Outdated Show resolved Hide resolved
@mostaphaRoudsari mostaphaRoudsari self-requested a review May 28, 2019 00:40
Copy link
Member

@mostaphaRoudsari mostaphaRoudsari left a comment

Choose a reason for hiding this comment

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

It looks good! Thank you for making all the changes. As discussed let's merge this in and we will know more about the performance as we integrate the library into other ladybug tools libraries.

@mostaphaRoudsari
Copy link
Member

PS: I suggest to squash and merge them as a single commit to end up with a cleaner git history and also make @AntoineDao happy! ;)

@AntoineDao
Copy link
Member

Realistically what would make me happy is smaller PRs merged more often rather than one spanning from end of March... But of well, you can't have it all I guess 😛

@AntoineDao
Copy link
Member

AntoineDao commented May 28, 2019

With regards to commit messages it's mostly for the sake of:

  1. Commit history review
  2. Semantic release version upgrades
  3. Changelog of semantic releases being meaningful

semantic police away!!!

@chriswmackey
Copy link
Member Author

Definitely going to Squash and merge this one. The only reason why I didn't do my semantic duty is because this is the first PR that is actually establishing the repo (all future PRs will be much more diligent). We definitely got carried away leaving this PR for 2 months and this should also not happen in the future.

@chriswmackey chriswmackey merged commit 4f85aa7 into ladybug-tools:development May 28, 2019
chriswmackey added a commit that referenced this pull request May 28, 2019
* feat(2d): More 2D Geometries

* Almost Done With All 2D Geometry

... there are just a couple of last things that I need to impelment on Mesh2D.

* Finished All 2D Objects

I still need to write some tests for them but all fundamental 2D objects are now complete.

* Added 1D Objects in 3D Space

* Finished 3D Geometries

I have been doing tests in Rhino just because it is quicker so I am fairly certain that 80% of the code is working.  I will begin writing pure Python tests and (likely) fixing bugs soon.

* Bug Fix to Surface Class

* Update README.md

* More Reliable is_point_inside method

* Documenting Fringe Cases

* Responding to comments by @mostaphaRoudsari

* Found a Better Way to Avoid Mesh Grid Fringe Cases

* Cleaning Up Code

I realized that one of the methods that I added previously did not do what I thought it did so I have removed it.  I also added a method to automatically create a single closed polygon from a shape with a hole.  I ran it through several tests in Rhino and it seems to be working well.  There aren't any cases I can think of that will not work with the general calculation method and I think I can get it to work for shapes with multiple hole just by having it recurse.

* Added the Capability to Have Faces with Holes

... and everything seems to be working well!

* Update dev-requirements.txt

* Finished Tests for Points

* Finished Tests for LineSegment

* Added Test for Ray2D

* Finished Tests for Rays

* More Polygon2D Tests

* More Tests for Mesh2D

* Decided to Remove the Ability to Override Checks

I realized that the overhad for the checks is not that bad and things really get wonky when they can be overridden on the class.

* Finished Tests for Polygon2D

* Finished All 2D Tests

... and fixed a lot of bugs / poor design decisions that were discovered in the process.

* Added Mesh3D Test

* Finished Mesh3D Tests

* Finished Tests for Plane

... and fixed a few bugs found along the way.

* Started Tests for Face3D

* More Face3D Tests

... and I added a method to Plane to test for co-planarity within a certain tolerance.

* Finished Tests

* Added Methods to Test Equivalency of Geometry

This is what I think should be used for solving adjacency and it has been optimized for this purpose.

* Added method to get sub faces by ratio

* Added Methods to Extract Rectangles from Faces

* Updated documentation

* Small Bug Fix in Plane

* Small Bug Fix in Face3D Sub Face Generation

* Finished All Methods for Glazing by Ratio

* Responded to Comments by @mostaphaRoudsari

... and I  realized that I forgot to add in methods last time to split rectangular glazing vertically, which is now added.

* All Geometry Objects are Now Immutable

This has simplified the code a lot and makes it much easier to communicate how to interact with the ladybug_geomtry API.  The only exception to the universal immutability rule is that the colors of mesh objects are set-able.

* Added Methods to Tell if a Face is Inside Another

* Added methods to generate contoured fins (aka. louvers)

* Added Object for Polyface

This should give us everything that we need to build energy model geometry in the way that we do now with honeybee legacy.  There are just a few small methods left that I want to implement on the Polyface3D object to make it consistent with the other objects.

* Added Transform Methods to Polyface

* Added Volume Property to Polyface

* Adding More Polyface tests

* Realized an Important Case that Needs Solving

* Polyface now has good checks for solidity

* Finished Polyface3D

* Fixed a Bug and Added Tests for it

* Responding to @mostaphaRoudsari 's comments on _mesh.py

* Changed Mesh Grid to Use a Scaled Polygon

* Added a Property to Get Upper Left Counter Clockwise Vertices

.. needed for export to EnergyPlus / OpenStudio

* Using try/except instead of if

* Update ladybug_geometry/_mesh.py

Co-Authored-By: Mostapha Sadeghipour Roudsari <sadeghipour@gmail.com>

* Bug Fix for Python Float Tolerance Cases

* Took Out scale_world_origin method

... and I just extended the scale() method.

* Adding __init__ and __repr__ to Base Classes

* Removing __slots__ from Base Classes

I relaized this creates issues

* Typo Fix

* Update README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
critical Features/fixes that are critical to continued development enhancement New feature or request new development For issues that require new code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants