package org.geogebra.common.geogebra3D.io; import java.util.LinkedHashMap; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPoint3D; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoQuadric3D; import org.geogebra.common.geogebra3D.main.settings.EuclidianSettingsForPlane; import org.geogebra.common.io.MyXMLHandler; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.kernelND.GeoPlaneND; import org.geogebra.common.kernel.kernelND.GeoPointND; import org.geogebra.common.kernel.kernelND.SurfaceEvaluable; import org.geogebra.common.kernel.kernelND.SurfaceEvaluable.LevelOfDetail; import org.geogebra.common.main.settings.EuclidianSettings; import org.geogebra.common.main.settings.EuclidianSettings3D; import org.geogebra.common.util.StringUtil; import org.geogebra.common.util.debug.Log; /** * Class extending MyXMLHandler for 3D * * @author ggb3D * * */ public class MyXMLHandler3D extends MyXMLHandler { /** * See Kernel3D for using the constructor * * @param kernel * kernel * @param cons * construction */ public MyXMLHandler3D(Kernel kernel, Construction cons) { super(kernel, cons); } // ==================================== // <euclidianView3D> only used in 3D // ==================================== /** * only used in MyXMLHandler3D * * @param eName * element name * @param attrs * attributes */ @Override protected void startEuclidianView3DElement(String eName, LinkedHashMap<String, String> attrs) { // must do this first if (evSet == null) { evSet = app.getSettings().getEuclidian(3); } // make sure eg is reset the first time (for each EV) we get the // settings // "viewNumber" not stored for EV1 so we need to do this here if (resetEVsettingsNeeded) { resetEVsettingsNeeded = false; evSet.reset(); } boolean ok = true; // EuclidianView3DInterface ev = app.getEuclidianView3D(); switch (eName.charAt(0)) { case 'a': if ("axesColor".equals(eName)) { // ok = handleAxesColor(ev, attrs); break; } else if ("axis".equals(eName)) { ok = handleAxis(evSet, attrs); break; } case 'b': if ("bgColor".equals(eName)) { ok = handleBgColor(evSet, attrs); break; } case 'c': if ("coordSystem".equals(eName)) { ok = handleCoordSystem3D((EuclidianSettings3D) evSet, attrs); break; } else if ("clipping".equals(eName)) { ok = handleClipping((EuclidianSettings3D) evSet, attrs); break; } case 'e': if ("evSettings".equals(eName)) { ok = handleEvSettings(evSet, attrs); break; } case 'g': if ("grid".equals(eName)) { ok = handleGrid(evSet, attrs); break; } /* * else if ("gridColor".equals(eName)) { ok = handleGridColor(ev, * attrs); break; } */ case 'l': if ("light".equals(eName)) { ok = handleLight((EuclidianSettings3D) evSet, attrs); break; } else if ("labelStyle".equals(eName)) { ok = handleLabelStyle(evSet, attrs); break; } case 'p': if ("plate".equals(eName) || "plane".equals(eName)) { ok = handlePlate((EuclidianSettings3D) evSet, attrs); break; } else if ("projection".equals(eName)) { ok = handleProjection((EuclidianSettings3D) evSet, attrs); break; } case 'y': if ("yAxisVertical".equals(eName)) { ok = handleYAxisIsUp((EuclidianSettings3D) evSet, attrs); break; } /* * * case 's': if ("size".equals(eName)) { ok = handleEvSize(ev, * attrs); break; } */ default: Log.error("unknown tag in <euclidianView3D>: " + eName); } if (!ok) { Log.error("error in <euclidianView3D>: " + eName); } } @Override protected void startGeoElement(String eName, LinkedHashMap<String, String> attrs) { if (geo == null) { Log.debug("no element set for <" + eName + ">"); return; } boolean ok = true; switch (eName.charAt(0)) { case 'f': if ("fading".equals(eName)) { ok = handleFading(attrs); break; } case 'l': if ("levelOfDetailQuality".equals(eName)) { ok = handleLevelOfDetailQuality(attrs); break; } default: super.startGeoElement(eName, attrs); } if (!ok) { Log.debug("error in <element>: " + eName); } } private static boolean handleCoordSystem3D(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { double xZero = Double.parseDouble(attrs.get("xZero")); double yZero = Double.parseDouble(attrs.get("yZero")); double zZero = Double.parseDouble(attrs.get("zZero")); double scale = Double.parseDouble(attrs.get("scale")); double yscale = scale, zscale = scale; String yScaleString = attrs.get("yscale"); if (yScaleString != null) { yscale = Double.parseDouble(yScaleString); } String zScaleString = attrs.get("zscale"); if (zScaleString != null) { zscale = Double.parseDouble(zScaleString); } double xAngle = Double.parseDouble(attrs.get("xAngle")); double zAngle = Double.parseDouble(attrs.get("zAngle")); evs.setXscale(scale); evs.setYscale(yscale); evs.setZscale(zscale); evs.setRotXYinDegrees(zAngle, xAngle); evs.updateOrigin(xZero, yZero, zZero); return true; } catch (Exception e) { return false; } } private boolean handleFading(LinkedHashMap<String, String> attrs) { try { float fading = Float.parseFloat(attrs.get("val")); ((GeoPlaneND) geo).setFading(fading); return true; } catch (Exception e) { return false; } } private boolean handleLevelOfDetailQuality( LinkedHashMap<String, String> attrs) { try { boolean lod = Boolean.parseBoolean(attrs.get("val")); if (lod) { ((SurfaceEvaluable) geo) .setLevelOfDetail(LevelOfDetail.QUALITY); } return true; } catch (Exception e) { return false; } } /** * handles plane attributes (show plate) for EuclidianView3D * * @param evs * settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handlePlate(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { String strShowPlate = attrs.get("show"); // show the plane if (strShowPlate != null) { boolean showPlate = parseBoolean(strShowPlate); evs.setShowPlate(showPlate); } return true; } catch (Exception e) { // e.printStackTrace(); return false; } } /** * handles plane attributes (show plate) for EuclidianView3D * * @param evs * settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handleYAxisIsUp(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { String strYAxisVertical = attrs.get("val"); // show the plane if (strYAxisVertical != null) { boolean yAxisVertical = parseBoolean(strYAxisVertical); evs.setYAxisVertical(yAxisVertical); } return true; } catch (Exception e) { // e.printStackTrace(); return false; } } /** * handles light attributes for EuclidianView3D * * @param evs * settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handleLight(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { String strLight = attrs.get("val"); // show the plane if (strLight != null) { boolean light = parseBoolean(strLight); evs.setUseLight(light); } return true; } catch (Exception e) { // e.printStackTrace(); return false; } } /** * handles plane attributes (show grid) for EuclidianView3D * * @param evs * euclidian settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handleGrid(EuclidianSettings evs, LinkedHashMap<String, String> attrs) { try { String strShowGrid = attrs.get("show"); // show the plane if (strShowGrid != null) { boolean showGrid = parseBoolean(strShowGrid); evs.showGrid(showGrid); } return true; } catch (Exception e) { // e.printStackTrace(); return false; } } /** * @param evs * settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handleClipping(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { String strUseClipping = attrs.get("use"); if (strUseClipping != null) { boolean useClipping = parseBoolean(strUseClipping); evs.setUseClippingCube(useClipping); } String strShowClipping = attrs.get("show"); if (strShowClipping != null) { boolean showClipping = parseBoolean(strShowClipping); evs.setShowClippingCube(showClipping); } String strSizeClipping = attrs.get("size"); if (strSizeClipping != null) { int sizeClipping = Integer.parseInt(strSizeClipping); evs.setClippingReduction(sizeClipping); } return true; } catch (Exception e) { // e.printStackTrace(); return false; } } /** * handles projection attribute * * @param evs * settings * @param attrs * attributes * @return true if all is done ok */ protected boolean handleProjection(EuclidianSettings3D evs, LinkedHashMap<String, String> attrs) { try { String strType = attrs.get("type"); if (strType != null) { int type = Integer.parseInt(strType); evs.setProjection(type); } String strDistance = attrs.get("distance"); if (strDistance != null) { int distance = Integer.parseInt(strDistance); evs.setProjectionPerspectiveEyeDistance(distance); } String strSep = attrs.get("separation"); if (strSep != null) { int sep = Integer.parseInt(strSep); evs.setEyeSep(sep); } String strAngle = attrs.get("obliqueAngle"); if (strAngle != null) { double angle = Double.parseDouble(strAngle); evs.setProjectionObliqueAngle(angle); } String strFactor = attrs.get("obliqueFactor"); if (strFactor != null) { double factor = Double.parseDouble(strFactor); evs.setProjectionObliqueFactor(factor); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** create absolute start point (coords expected) */ @Override protected GeoPointND handleAbsoluteStartPoint( LinkedHashMap<String, String> attrs) { double x = Double.parseDouble(attrs.get("x")); double y = Double.parseDouble(attrs.get("y")); double z = Double.parseDouble(attrs.get("z")); String wStr = attrs.get("w"); GeoPointND p; if (wStr != null) { // 3D double w = Double.parseDouble(wStr); p = new GeoPoint3D(cons); p.setCoords(x, y, z, w); } else { // 2D p = new GeoPoint(cons); p.setCoords(x, y, z); } return p; } @Override protected void startEuclidianViewElementCheckViewId(String eName, LinkedHashMap<String, String> attrs) { if ("viewId".equals(eName)) { String plane = attrs.get("plane"); evSet = app.getSettings().getEuclidianForPlane(plane); if (evSet == null) { evSet = new EuclidianSettingsForPlane(app); app.getSettings().setEuclidianSettingsForPlane(plane, evSet); } ((EuclidianSettingsForPlane) evSet).setFromLoadFile(true); } } @Override protected boolean startEuclidianViewElementSwitch(String eName, LinkedHashMap<String, String> attrs, char firstChar) { if (firstChar == 't') { if ("transformForPlane".equals(eName)) { return handleTransformForPlane( (EuclidianSettingsForPlane) evSet, attrs); } } return super.startEuclidianViewElementSwitch(eName, attrs, firstChar); } private static boolean handleTransformForPlane(EuclidianSettingsForPlane ev, LinkedHashMap<String, String> attrs) { try { ev.setTransformForPlane(Boolean.parseBoolean(attrs.get("mirror")), Integer.parseInt(attrs.get("rotate"))); return true; } catch (Exception e) { return false; } } @Override protected void handleMatrixConicOrQuadric( LinkedHashMap<String, String> attrs) throws Exception { if (geo.isGeoQuadric()) { if (geo.isDefaultGeo()) { // avoid setting for default geo return; } GeoQuadric3D quadric = (GeoQuadric3D) geo; // set matrix and classify conic now // <eigenvectors> should have been set earlier double[] matrix = { StringUtil.parseDouble(attrs.get("A0")), StringUtil.parseDouble(attrs.get("A1")), StringUtil.parseDouble(attrs.get("A2")), StringUtil.parseDouble(attrs.get("A3")), StringUtil.parseDouble(attrs.get("A4")), StringUtil.parseDouble(attrs.get("A5")), StringUtil.parseDouble(attrs.get("A6")), StringUtil.parseDouble(attrs.get("A7")), StringUtil.parseDouble(attrs.get("A8")), StringUtil.parseDouble(attrs.get("A9")) }; quadric.setMatrixFromXML(matrix); } else { super.handleMatrixConicOrQuadric(attrs); } } @Override protected boolean handleEigenvectors(LinkedHashMap<String, String> attrs) { if (!(geo.isGeoQuadric())) { return super.handleEigenvectors(attrs); } try { GeoQuadric3D quadric = (GeoQuadric3D) geo; // set eigenvectors, but don't classify conic now // classifyConic() will be called in handleMatrix() by // conic.setMatrix() quadric.setEigenvectors(StringUtil.parseDouble(attrs.get("x0")), StringUtil.parseDouble(attrs.get("y0")), StringUtil.parseDouble(attrs.get("z0")), StringUtil.parseDouble(attrs.get("x1")), StringUtil.parseDouble(attrs.get("y1")), StringUtil.parseDouble(attrs.get("z1")), StringUtil.parseDouble(attrs.get("x2")), StringUtil.parseDouble(attrs.get("y2")), StringUtil.parseDouble(attrs.get("z2"))); return true; } catch (Exception e) { return false; } } }