Giter Site home page Giter Site logo

blockresearchgroup / compas_3gs Goto Github PK

View Code? Open in Web Editor NEW
10.0 10.0 7.0 200.4 MB

3D graphic statics add-on for the COMPAS framework

Home Page: https://blockresearchgroup.github.io/compas_3gs/

License: MIT License

Python 100.00%
3d form-finding graphic-statics polyhedral-diagrams

compas_3gs's People

Contributors

dependabot[bot] avatar duchaoyu avatar juney-lee avatar licini avatar tomvanmele avatar wenqian157 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

compas_3gs's Issues

conduit doesn't work

In COMPAS_3GS\examples\00_20_cell_arearise_face, the callback function should visualise the iterative arearisation process.
However, the iteration process shown in [https://blockresearchgroup.github.io/compas_3gs/user_manual/00_polyhedral_cell/00_11_cell_arearise_face.html] cannot be redrawn successfully. I only get the final polyhedron cell.
I've checked the callback works... I think the problem is in the conduit display or somewhere else...

from __future__ import absolute_import
from __future__ import print_function
from __future__ import division

import time

import compas

from compas_rhino import unload_modules
unload_modules('compas')

from compas.geometry import dot_vectors
from compas.utilities import i_to_blue

from compas_rhino.geometry import RhinoSurface
from compas_rhino.selectors import FaceSelector

from compas_3gs.algorithms import cell_arearise_face
from compas_3gs.diagrams import Cell
from compas_3gs.operations import cell_relocate_face
from compas_3gs.rhino import MeshConduit
from compas_3gs.datastructures import Mesh3gsArtist

try:
    import rhinoscriptsyntax as rs

except ImportError:
    compas.raise_if_ironpython()


__author__     = 'Juney Lee'
__copyright__  = 'Copyright 2019, BLOCK Research Group - ETH Zurich'
__license__    = 'MIT License'
__email__      = '[email protected]'


# ------------------------------------------------------------------------------
#   1. make cell from rhino polysurfaces
# ------------------------------------------------------------------------------
# select the polysurface which you create in Rhino
guid = rs.GetObject("select a closed polysurface", filter=rs.filter.polysurface)
# turn Rhino polysurface to a COMPAS single polyhedral cell
cell = RhinoSurface.from_guid(guid).brep_to_compas(cls=Cell())

# draw the polyhedral cell
layer = 'cell' 
cellartist = Mesh3gsArtist(cell, layer=layer)
cellartist.draw()
# hide Rhino polysurface
rs.HideObjects(guid)


# ------------------------------------------------------------------------------
#   2. Target area
# ------------------------------------------------------------------------------
# select a mesh face and get its face key, area, center point and normal vector
fkey   = FaceSelector.select_face(cell)
area   = cell.face_area(fkey)
center = cell.face_centroid(fkey)
normal = cell.face_normal(fkey)

# input target area value, current face area is shown as a reference
target_area = rs.GetReal("Enter target area", number=area)


# ------------------------------------------------------------------------------
#   3. Arearise cell face
# ------------------------------------------------------------------------------
# conduit
conduit = MeshConduit(cell, refreshrate=1)

    
def callback(cell, args=None):
    current_area = cell.face_area(fkey)
    color  = i_to_blue(abs(current_area - target_area) / target_area)
    conduit.face_colordict = {fkey: color}
    time.sleep(0.05)
    conduit.redraw(k=1)

with conduit.enabled():
    cell_arearise_face(cell,
                       fkey,
                       target_area,
                       callback=callback)


# ------------------------------------------------------------------------------
#   4. Check result
# ------------------------------------------------------------------------------
new_area   = cell.face_area(fkey)
new_normal = cell.face_normal(fkey)

# WHAT IS THIS FOR? NEW AREA SHOULD ANYWAY BE BIGGER THAN 0? 
if dot_vectors(normal, new_normal) < 0:
    new_area *= -1

# check whether the arearisation succeed
if abs(new_area - target_area) > 1:
    print('===================================================================')
    print('')
    print('Arearisation attempted, but did not converge...')
    print('It is likely that the target area is not valid / inexistent...')
    print('')
    print('===================================================================')

    # retrieve the origianl mesh face
    cell_relocate_face(cell, fkey, center, normal)


# ------------------------------------------------------------------------------
#   5. Draw result
# ------------------------------------------------------------------------------
new_layer = 'arearised_cell' 
new_cellartist = Mesh3gsArtist(cell, layer=new_layer)
new_cellartist.draw()


is it possible to make artist an inner class?

here is my current version of mesh3gs artist.... it works well....

from __future__ import absolute_import
from __future__ import print_function
from __future__ import division

from copy import deepcopy

from compas.datastructures import Mesh

from compas.datastructures import mesh_split_face

from compas.geometry import subtract_vectors
from compas.geometry import normalize_vector
from compas.geometry import length_vector
from compas.geometry import cross_vectors

from compas_rhino.artists import MeshArtist

from compas_3gs.utilities import polygon_normal_oriented
from compas_3gs.utilities import polygon_area_oriented
from compas_3gs.utilities import datastructure_centroid


__author__     = 'Juney Lee'
__copyright__  = 'Copyright 2019, BLOCK Research Group - ETH Zurich'
__license__    = 'MIT License'
__email__      = '[email protected]'


__all__ = ['Mesh3gs',
            'Mesh3gsArtist',]


class Mesh3gs(Mesh):
    """Inherits and extends the compas Mesh class, such that it is more suitable for 3D graphic statics applications.

    Primarily used for the EGI.

    """

    def __init__(self):
        super(Mesh3gs, self).__init__()

    # --------------------------------------------------------------------------
    #   inherited
    # --------------------------------------------------------------------------

    mesh_split_face        = mesh_split_face
    datastructure_centroid = datastructure_centroid

    def add_edge(self, u, v, attr_dict=None, **kwattr):

        attr = deepcopy(self.default_edge_attributes)
        if not attr_dict:
            attr_dict = {}
        attr_dict.update(kwattr)
        attr.update(attr_dict)

        if u not in self.vertex:
            u = self.add_vertex(u)
        if v not in self.vertex:
            v = self.add_vertex(v)

        data = self.edge[u].get(v, {})
        data.update(attr)

        self.edge[u][v] = data
        if v not in self.halfedge[u]:
            self.halfedge[u][v] = None
        if u not in self.halfedge[v]:
            self.halfedge[v][u] = None

        return u, v

    # --------------------------------------------------------------------------
    # helpers - vertices
    # --------------------------------------------------------------------------

    def vertex_update_xyz(self, vkey, xyz, constrained=True):
        if constrained:
            # X
            if self.vertex[vkey]['x_fix'] is False:
                self.vertex[vkey]['x'] = xyz[0]
            # Y
            if self.vertex[vkey]['y_fix'] is False:
                self.vertex[vkey]['y'] = xyz[1]
            # Z
            if self.vertex[vkey]['z_fix'] is False:
                self.vertex[vkey]['z'] = xyz[2]
        else:
            self.vertex[vkey]['x'] = xyz[0]
            self.vertex[vkey]['y'] = xyz[1]
            self.vertex[vkey]['z'] = xyz[2]

    # --------------------------------------------------------------------------
    # helpers - faces
    # --------------------------------------------------------------------------

    def face_area(self, fkey):
        points = self.face_coordinates(fkey)
        area   = polygon_area_oriented(points)
        return area

    def face_normal(self, fkey, unitized=True):
        points = self.face_coordinates(fkey)
        normal = polygon_normal_oriented(points, unitized)
        if length_vector(normal) == 0 :
            uv     = subtract_vectors(points[1], points[0])
            vw     = subtract_vectors(points[2], points[1])
            normal = normalize_vector(cross_vectors(uv, vw))
        return normal


class Mesh3gsArtist(MeshArtist):
    """Inherits the compas :class:`MeshArtist`, provides functionality for visualisation of 3D graphic statics applications.

    """
    def __init__(self, cell, layer=None):
        super(Mesh3gsArtist, self).__init__(cell, layer=layer)


# ******************************************************************************
# ******************************************************************************
# ******************************************************************************
#
#   Main
#
# ******************************************************************************
# ******************************************************************************
# ******************************************************************************


if __name__ == '__main__':
    pass

but it's relatively complex to write Mesh3gsArtist everytime I wanna draw something.
I'm thinking whether it's possible to make artist an inner class, cause i could use mesh3gs.artist.draw() for example...
I tried the following... but it seems it doesn't work. / maybe I don't use it correctly. Does someone have any idea?

class Mesh3gs(Mesh):

    def __init__(self):
        super(Mesh3gs, self).__init__()
        self.artist = self.Mesh3gsArtist()

    class Mesh3gsArtist(MeshArtist):
        def __init__(self, cell, layer=None):
             super(Mesh3gsArtist, self).__init__(cell, layer=layer)

I always get the error of Mesh3gs has no attribute of Mesh3gsArtist......

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.