diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java index ab3b39f3c4e3607d4892dc6b9545c6efedf5012e..27694b38cf2debea774354777d07d48b5850942b 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java @@ -1,173 +1,173 @@ -package cz.fidentis.analyst.mesh.core; - -import com.google.common.eventbus.EventBus; -import java.util.ArrayList; -import java.util.List; -import cz.fidentis.analyst.mesh.MeshVisitor; -import cz.fidentis.analyst.mesh.events.FacetAddedEvent; -import java.util.Collections; -import cz.fidentis.analyst.mesh.events.MeshListener; -import java.io.Serializable; -import java.util.Collection; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * The main object for triangular meshes. Each mesh model consists - * of one or more mesh facets. - * <p> - * This class implements the publish-subscribe notifications to changes. - * However, the {@code HumanFace} class provides similar - * functionality at the higher level of abstraction. Therefore, we recommend - * to monitor this class when you want to be informed about changes in concrete human face. - * <p> - * Events fired by the class: - * <ul> - * <li>{@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} when new facet is added.</li> - * </ul> - * </p> - * - * @author Matej Lukes - * @author Radek Oslejsek - */ -public class MeshModel implements Serializable { - - private final List<MeshFacet> facets = new ArrayList<>(); - - private final transient EventBus eventBus = new EventBus(); - - /** - * Constructor of MeshModel - */ - public MeshModel() { - - } - - /** - * Copy constructor of MeshModel - * - * @param meshModel copied MeshModel - */ - public MeshModel(MeshModel meshModel) { - for (MeshFacet facet: meshModel.facets) { - facets.add(new MeshFacetImpl(facet)); - } - } - - /** - * returns list of MeshFacets - * - * @return list of MeshFacets - */ - public List<MeshFacet> getFacets() { - return Collections.unmodifiableList(facets); - } - - /** - * Adds a new mesh facet to the model. - * Fires {@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} to - * registered listeners. - * - * @param facet new MeshFacet - */ - public void addFacet(MeshFacet facet) { - facets.add(facet); - eventBus.post(new FacetAddedEvent(facet)); - } - - /** - * Adds a new mesh facets to the model. - * Fires {@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} to - * registered listeners. - * - * @param facet new MeshFacet - */ - public void addFacets(Collection<MeshFacet> facets) { - facets.addAll(facets); - for (MeshFacet f: facets) { - eventBus.post(new FacetAddedEvent(f)); - } - } - - /** - * Applies the visitor to all mesh facets. If the visitor is thread-safe - * and the {@code concurrently} is {@code true}, then the visitor is - * applied to all mesh facet concurrently using all CPU cores. - * - * @param visitor Visitor to be applied for the computation - * @param concurrently Parallel computation - * @throws NullPointerException if the visitor is {@code null} - */ - public void compute(MeshVisitor visitor, boolean concurrently) { - if (concurrently && visitor.isThreadSafe()) { - ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - - for (MeshFacet f: this.facets) { - Runnable worker = new Runnable() { - @Override - public void run() { - f.accept(visitor); - } - }; - executor.execute(worker); - } - - // Wait until all symmetry planes are computed: - executor.shutdown(); - while (!executor.isTerminated()){} - } else { - for (MeshFacet f: this.facets) { - f.accept(visitor); - } - } - } - - /** - * Applies the visitor to all mesh facets sequentially. - * - * @param visitor Visitor to be applied for the computation - * @throws NullPointerException if the visitor is {@code null} - */ - public void compute(MeshVisitor visitor) { - compute(visitor, false); - } - - /** - * Registers listeners (objects concerned in the mesh model changes) to receive events. - * If listener is {@code null}, no exception is thrown and no action is taken. - * - * @param listener Listener concerned in the mesh model changes. - */ - public void registerListener(MeshListener listener) { - eventBus.register(listener); - } - - /** - * Unregisters listeners from receiving events. - * - * @param listener Registered listener - */ - public void unregisterListener(MeshListener listener) { - eventBus.unregister(listener); - } - - /** - * Removes duplicate vertices that differ only in normal vectors or texture coordinates. - * Multiple normals are replaced with the average normal. If the texture coordinate - * differ then randomly selected one is used. - */ - public void simplifyModel() { - for (MeshFacet f : this.facets) { - f.simplify(); - } - } - - @Override - public String toString() { - int verts = 0; - for (MeshFacet f: facets) { - verts += f.getNumberOfVertices(); - } - return facets.size() + " facets with " + verts + " vertices"; - } -} +package cz.fidentis.analyst.mesh.core; + +import com.google.common.eventbus.EventBus; +import java.util.ArrayList; +import java.util.List; +import cz.fidentis.analyst.mesh.MeshVisitor; +import cz.fidentis.analyst.mesh.events.FacetAddedEvent; +import java.util.Collections; +import cz.fidentis.analyst.mesh.events.MeshListener; +import java.io.Serializable; +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * The main object for triangular meshes. Each mesh model consists + * of one or more mesh facets. + * <p> + * This class implements the publish-subscribe notifications to changes. + * However, the {@code HumanFace} class provides similar + * functionality at the higher level of abstraction. Therefore, we recommend + * to monitor this class when you want to be informed about changes in concrete human face. + * <p> + * Events fired by the class: + * <ul> + * <li>{@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} when new facet is added.</li> + * </ul> + * </p> + * + * @author Matej Lukes + * @author Radek Oslejsek + */ +public class MeshModel implements Serializable { + + private final List<MeshFacet> facets = new ArrayList<>(); + + private final transient EventBus eventBus = new EventBus(); + + /** + * Constructor of MeshModel + */ + public MeshModel() { + + } + + /** + * Copy constructor of MeshModel + * + * @param meshModel copied MeshModel + */ + public MeshModel(MeshModel meshModel) { + for (MeshFacet facet: meshModel.facets) { + facets.add(new MeshFacetImpl(facet)); + } + } + + /** + * returns list of MeshFacets + * + * @return list of MeshFacets + */ + public List<MeshFacet> getFacets() { + return Collections.unmodifiableList(facets); + } + + /** + * Adds a new mesh facet to the model. + * Fires {@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} to + * registered listeners. + * + * @param facet new MeshFacet + */ + public void addFacet(MeshFacet facet) { + facets.add(facet); + eventBus.post(new FacetAddedEvent(facet)); + } + + /** + * Adds a new mesh facets to the model. + * Fires {@link cz.fidentis.analyst.mesh.events.FacetAddedEvent} to + * registered listeners. + * + * @param newFacets collection of new new facets + */ + public void addFacets(Collection<MeshFacet> newFacets) { + facets.addAll(newFacets); + for (MeshFacet f: newFacets) { + eventBus.post(new FacetAddedEvent(f)); + } + } + + /** + * Applies the visitor to all mesh facets. If the visitor is thread-safe + * and the {@code concurrently} is {@code true}, then the visitor is + * applied to all mesh facet concurrently using all CPU cores. + * + * @param visitor Visitor to be applied for the computation + * @param concurrently Parallel computation + * @throws NullPointerException if the visitor is {@code null} + */ + public void compute(MeshVisitor visitor, boolean concurrently) { + if (concurrently && visitor.isThreadSafe()) { + ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + for (MeshFacet f: this.facets) { + Runnable worker = new Runnable() { + @Override + public void run() { + f.accept(visitor); + } + }; + executor.execute(worker); + } + + // Wait until all symmetry planes are computed: + executor.shutdown(); + while (!executor.isTerminated()){} + } else { + for (MeshFacet f: this.facets) { + f.accept(visitor); + } + } + } + + /** + * Applies the visitor to all mesh facets sequentially. + * + * @param visitor Visitor to be applied for the computation + * @throws NullPointerException if the visitor is {@code null} + */ + public void compute(MeshVisitor visitor) { + compute(visitor, false); + } + + /** + * Registers listeners (objects concerned in the mesh model changes) to receive events. + * If listener is {@code null}, no exception is thrown and no action is taken. + * + * @param listener Listener concerned in the mesh model changes. + */ + public void registerListener(MeshListener listener) { + eventBus.register(listener); + } + + /** + * Unregisters listeners from receiving events. + * + * @param listener Registered listener + */ + public void unregisterListener(MeshListener listener) { + eventBus.unregister(listener); + } + + /** + * Removes duplicate vertices that differ only in normal vectors or texture coordinates. + * Multiple normals are replaced with the average normal. If the texture coordinate + * differ then randomly selected one is used. + */ + public void simplifyModel() { + for (MeshFacet f : this.facets) { + f.simplify(); + } + } + + @Override + public String toString() { + int verts = 0; + for (MeshFacet f: facets) { + verts += f.getNumberOfVertices(); + } + return facets.size() + " facets with " + verts + " vertices"; + } +}