Print at Dec 16, 2018 4:59:42 PM

Posted by cungchoi at Dec 26, 2014 7:10:40 AM
Re: Sample plugin does not start
Right, I think my exe file is not up to date. Fine now though.
BTW, I modified your plugin Compute Walls Surface for my purpose and just for it (being messy of course), still I post it here if anyone bother to test or use it.
don't know how to attach a file

//version 25 Dec 2014
//- added ability to approximate curved walls
//- added ability to work for multilevel building
//- corrected slope walls
//- filter openings substractions by Doors & windows only
//- approximate doors & windows positions to prefer more inclusions. CAUTION: may have side effects when a door or windows is in vicinity of more than one wall on any level

package com.eteks.calculateWalls;

import java.awt.geom.Point2D;
import java.lang.reflect.Method;
import java.util.ArrayList;

import com.eteks.sweethome3d.model.HomePieceOfFurniture;
import com.eteks.sweethome3d.model.Selectable;
import com.eteks.sweethome3d.model.Wall;
import com.eteks.sweethome3d.plugin.Plugin;
import com.eteks.sweethome3d.plugin.PluginAction;

import javax.swing.JOptionPane;

class CalculateWallsAction extends PluginAction {

private final Plugin plugin;

public CalculateWallsAction(ClassLoader loader, Plugin plugin){
putPropertyValue(Property.NAME, "Compute walls' area");
putPropertyValue(Property.MENU, "Tools");

this.plugin = plugin;
// Enables the action by default

private void showInfo(float size) {
String message = "The walls' area currently is: "+size+" m\u00B2.";
if(size == 0)
message = "Please select at least one wall.";
JOptionPane.showMessageDialog(null, message);

private boolean inWall(Wall w, float x, float y)
//if(x >= Math.min(w.getXStart(), w.getXEnd()) && x <= Math.max(w.getXStart(), w.getXEnd()) && y >= Math.min(w.getYStart(), w.getYEnd()) && y <= Math.max(w.getYStart(), w.getYEnd()))
float cmpRate = 0;
//generalize- just one end near the wall surface, there are two cases:
//case 1: an arc wall
if(w.getArcExtent() != null)
float [] arcCircleCenter;
float arcCircleRadius;
Method m = Wall.class.getDeclaredMethod("getArcCircleCenter");
//m.invoke(d);// throws java.lang.IllegalAccessException
m.setAccessible(true);// Abracadabra
arcCircleCenter = (float[]) m.invoke(w);// now its OK
arcCircleRadius = (float)Point2D.distance(w.getXStart(), w.getYStart(),
arcCircleCenter [0], arcCircleCenter [1]);
cmpRate =(float)Point2D.distance(x,y,arcCircleCenter [0], arcCircleCenter [1])/arcCircleRadius;
} catch (Exception e) {
float dist2Start = (float)Point2D.distance(x,y,w.getXStart(), w.getYStart());
cmpRate = (dist2Start + (float)Point2D.distance(x,y,w.getXEnd(), w.getYEnd()))/w.getLength();
if((cmpRate > 0.9)&&(cmpRate< 1.1)) return true;
return false;

public void execute() {
float size = 0;

ArrayList<Wall> walls = new ArrayList<Wall>();
for(Selectable sel : plugin.getHome().getSelectedItems())
if(sel instanceof Wall)
Wall wall = (Wall) sel;

//if(wall.getArcExtent() == null)
size += (wall.getHeight() + ((wall.getHeightAtEnd()==null)? wall.getHeight():wall.getHeightAtEnd()) )*wall.getLength()/2.0;

//substracts openings
for(HomePieceOfFurniture furniture : plugin.getHome().getFurniture())
&& wall.isAtLevel(furniture.getLevel())
&& inWall(wall, furniture.getX(), furniture.getY()))
size -= (furniture.getHeight()*furniture.getWidth());


size /= 10000;