Ticket #908: issue_908.patch

File issue_908.patch, 5.8 KB (added by Rodrigo Rodrigues da Silva, 10 years ago)
  • mediagoblin/media_types/stl/migrations.py

    From 72fec22d4b22b7a5b1b953393d183b1236417a50 Mon Sep 17 00:00:00 2001
    From: Rodrigo Rodrigues da Silva <rsilva@metamaquina.com.br>
    Date: Mon, 9 Jun 2014 11:32:11 -0300
    Subject: [PATCH] Add (optional) volume calculation to STL files.
    
    ---
     mediagoblin/media_types/stl/migrations.py          |   14 +++++++
     mediagoblin/media_types/stl/model_loader.py        |   43 +++++++++++++++++---
     mediagoblin/media_types/stl/models.py              |    1 +
     mediagoblin/media_types/stl/processing.py          |    1 +
     .../templates/mediagoblin/media_displays/stl.html  |    4 ++
     5 files changed, 58 insertions(+), 5 deletions(-)
    
    diff --git a/mediagoblin/media_types/stl/migrations.py b/mediagoblin/media_types/stl/migrations.py
    index f54c23e..64edca1 100644
    a b  
    1414# You should have received a copy of the GNU Affero General Public License
    1515# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    1616
     17from sqlalchemy import MetaData, Table, Column, Float
     18from mediagoblin.db.migration_tools import RegisterMigration
     19
    1720MIGRATIONS = {}
     21
     22@RegisterMigration(1, MIGRATIONS)
     23def add_volume_column(db_conn):
     24    metadata = MetaData(bind=db_conn.bind)
     25
     26    stl_data = Table('stl__mediadata', metadata, autoload=True,
     27            autoload_with=db_conn.bind)
     28
     29    col = Column('volume', Float, nullable=True)
     30    col.create(stl_data)
     31    db_conn.commit()
  • mediagoblin/media_types/stl/model_loader.py

    diff --git a/mediagoblin/media_types/stl/model_loader.py b/mediagoblin/media_types/stl/model_loader.py
    index 88f1931..14f0ba1 100644
    a b  
    11# GNU MediaGoblin -- federated, autonomous media hosting
    2 # Copyright (C) 2011, 2012 MediaGoblin contributors.  See AUTHORS.
     2# Copyright (C) 2011, 2012, 2014 MediaGoblin contributors.  See AUTHORS.
    33#
    44# This program is free software: you can redistribute it and/or modify
    55# it under the terms of the GNU Affero General Public License as published by
     
    1616
    1717
    1818import struct
     19import logging
    1920
     21_use_admesh = True
     22try:
     23    import admesh
     24except:
     25    _use_admesh = False
     26
     27_log = logging.getLogger(__name__)
    2028
    2129class ThreeDeeParseError(Exception):
    2230    pass
    2331
    2432
    25 class ThreeDee():
     33class ThreeDee(object):
    2634    """
    2735    3D model parser base class.  Derrived classes are used for basic
    2836    analysis of 3D models, and are not intended to be used for 3D
    class ThreeDee():  
    3745        self.width = 0  # x axis
    3846        self.depth = 0  # y axis
    3947        self.height = 0 # z axis
     48        self.volume = None
    4049
    4150        self.load(fileob)
    4251        if not len(self.verts):
    class ObjModel(ThreeDee):  
    8392            line = line.strip()
    8493            if line[0] == "v":
    8594                self.verts.append(self.__vector(line))
    86            
    8795
    88 class BinaryStlModel(ThreeDee):
     96class StlModel(ObjModel):
     97    """
     98    General parser for STL models. This class provides a wrapper
     99    method to use admesh to calculate STL file volume (admesh can't
     100    parse OBJ files)
     101    """
     102
     103    def __volume(self, fileob):
     104        if _use_admesh:
     105            stl_file = admesh.stl_file()
     106            admesh.stl_open(stl_file, str(fileob.name))
     107            admesh.stl_calculate_volume(stl_file)
     108            self.volume = stl_file.stats.volume
     109
     110    def __init__(self, fileob):
     111        super(StlModel, self).__init__(fileob)
     112        if _use_admesh:
     113            _log.info("Using admesh to calculate volume")
     114            self.__volume(fileob)
     115        else:
     116            _log.warn("Admesh not installed. Bypassing volume calculation. ")
     117
     118    def load(self, fileob):
     119        super(ObjModel,self).load(fileob)
     120
     121class BinaryStlModel(StlModel):
    89122    """
    90123    Parser for ascii-encoded stl files.  File format reference:
    91124    http://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL
    def auto_detect(fileob, hint):  
    117150            # HACK Ascii formatted stls are similar enough to obj
    118151            # files that we can just use the same parser for both.
    119152            # Isn't that something?
    120             return ObjModel(fileob)
     153            return StlModel(fileob)
    121154        except ThreeDeeParseError:
    122155            pass
    123156        except ValueError:
  • mediagoblin/media_types/stl/models.py

    diff --git a/mediagoblin/media_types/stl/models.py b/mediagoblin/media_types/stl/models.py
    index ff50e9c..c8d4c2f 100644
    a b class StlData(Base):  
    4242    width = Column(Float)
    4343    height = Column(Float)
    4444    depth = Column(Float)
     45    volume = Column(Float)
    4546
    4647    file_type = Column(String)
    4748
  • mediagoblin/media_types/stl/processing.py

    diff --git a/mediagoblin/media_types/stl/processing.py b/mediagoblin/media_types/stl/processing.py
    index 65a8623..d36d42a 100644
    a b class CommonStlProcessor(MediaProcessor):  
    253253            "width": self.model.width,
    254254            "height": self.model.height,
    255255            "depth": self.model.depth,
     256            "volume": self.model.volume,
    256257            "file_type": self.ext,
    257258            }
    258259        self.entry.media_data_init(**dimensions)
  • mediagoblin/templates/mediagoblin/media_displays/stl.html

    diff --git a/mediagoblin/templates/mediagoblin/media_displays/stl.html b/mediagoblin/templates/mediagoblin/media_displays/stl.html
    index ca0479c..85f50a4 100644
    a b window.show_things = function () {  
    146146<p>{{ media.media_data.file_type }}</p>
    147147<h3>{% trans %}Object Height{% endtrans %}</h3>
    148148<p>~{{ media.media_data.height|int }} mm</p>
     149{% if media.media_data.volume %}
     150<h3>{% trans %}Object Volume{% endtrans %}</h3>
     151<p>~{{ media.media_data.volume|int }} mm³</p>
     152{% endif %}
    149153{% endblock %}