import { useEffect, useMemo, useRef, useState } from 'react' import PropTypes from 'prop-types' import NewObjectForm from '../../common/NewObjectForm' import ObjectForm from '../../common/ObjectForm' import ObjectInfo from '../../common/ObjectInfo' import WizardView from '../../common/WizardView' import { FILAMENT_PROFILE_BED_TEMPERATURE_PROPERTIES, FILAMENT_PROFILE_COMPATIBILITY_PROPERTIES, FILAMENT_PROFILE_COOLING_PROPERTIES, FILAMENT_PROFILE_EXHAUST_FAN_PROPERTIES, FILAMENT_PROFILE_FLOW_PRESSURE_PROPERTIES, FILAMENT_PROFILE_MATERIAL_PROPERTIES, FILAMENT_PROFILE_SPEED_PROPERTIES, FILAMENT_PROFILE_TEMPERATURE_PROPERTIES } from '../../../../database/models/FilamentProfile' const PRUSA_GENERIC_PETG_DEFAULTS = { filamentType: 'filament', filamentIsSupport: false, filamentSoluble: false, filamentPrintable: 3, filamentAdhesivenessCategory: 0, temperatureVitrification: 80, idleTemperature: 0, pelletFlowCoefficient: 0.4157, requiredNozzleHrc: 0, filamentFlowRatio: 0.98, enablePressureAdvance: false, pressureAdvance: 0.02, adaptivePressureAdvance: false, adaptivePressureAdvanceBridges: false, adaptivePressureAdvanceOverhangs: false, adaptivePressureAdvanceModel: '0,0,0\n0,0,0', activateChamberTempControl: false, chamberTemperature: 0, chamberMinimalTemperature: 0, nozzleTemperatureInitialLayer: 230, nozzleTemperature: 240, nozzleTemperatureRangeLow: 220, nozzleTemperatureRangeHigh: 260, hotPlateTempInitialLayer: 85, hotPlateTemp: 85, coolPlateTempInitialLayer: 60, coolPlateTemp: 60, engPlateTempInitialLayer: 0, engPlateTemp: 0, texturedPlateTempInitialLayer: 45, texturedPlateTemp: 45, texturedCoolPlateTempInitialLayer: 40, texturedCoolPlateTemp: 40, supertackPlateTempInitialLayer: 35, supertackPlateTemp: 35, filamentAdaptiveVolumetricSpeed: false, filamentMaxVolumetricSpeed: 8, volumetricSpeedCoefficients: '', closeFanTheFirstXLayers: 3, fullFanSpeedLayer: 0, fanMinSpeed: 40, fanMaxSpeed: 90, reduceFanStopStartFreq: true, slowDownForLayerCooling: true, dontSlowDownOuterWall: false, slowDownMinSpeed: 10, slowDownLayerTime: 8, fanCoolingLayerTime: 30, enableOverhangBridgeFan: true, overhangFanThreshold: '25%', overhangFanSpeed: 90, internalBridgeFanSpeed: -1, supportMaterialInterfaceFanSpeed: -1, ironingFanSpeed: -1, initialLayerFanSpeed: -1, firstXLayerFanSpeed: 0, additionalCoolingFanSpeed: 0, additionalFanFullSpeedLayer: 0, closeAdditionalFanFirstXLayers: true, activateAirFiltration: false, activateAirFiltrationDuringPrint: true, activateAirFiltrationOnCompletion: true, duringPrintExhaustFanSpeed: 60, completePrintExhaustFanSpeed: 80, filamentLoadingSpeed: 28, filamentLoadingSpeedStart: 3, filamentUnloadingSpeed: 90, filamentUnloadingSpeedStart: 100, filamentChangeLength: 10, filamentChangeLengthNc: 10, filamentToolchangeDelay: 0, filamentExtruderCompatibility: 0, filamentExtruderVariant: 'Direct Drive Standard', filamentMultitoolRamming: false, filamentMultitoolRammingFlow: 10, filamentMultitoolRammingVolume: 10, filamentRammingParameters: '120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6', filamentRammingTravelTime: 0, filamentRammingTravelTimeNc: 0, filamentRammingVolumetricSpeed: -1, filamentRammingVolumetricSpeedNc: -1, filamentMinimalPurgeOnWipeTower: 15, filamentTowerInterfacePreExtrusionDist: 10, filamentTowerInterfacePreExtrusionLength: 0, filamentTowerInterfacePrintTemp: -1, filamentTowerInterfacePurgeVolume: 20, filamentTowerIroningArea: 4, filamentCoolingBeforeTower: 10, filamentCoolingInitialSpeed: 2.2, filamentCoolingFinalSpeed: 3.4, filamentCoolingMoves: 4, filamentFlushTemp: 0, filamentFlushTempFast: 0, filamentFlushVolumetricSpeed: 0, filamentPreCoolingTemperature: 0, filamentPreCoolingTemperatureNc: 0, filamentPreheatTemperatureDelta: 0, filamentPrimeVolumeNc: 60, filamentStampingDistance: 0, filamentStampingLoadingSpeed: 0, longRetractionsWhenEc: false, retractionDistancesWhenEc: 10, filamentStartGcode: '; filament start gcode\nM900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.08{endif} ; Filament gcode LA 1.5', filamentEndGcode: '; filament end gcode \n', filamentChangeExtrusionRoleGcode: '', filamentShrink: '100%', filamentShrinkageCompensationZ: '100%', compatiblePrinters: [], compatiblePrintersCondition: '', compatiblePrints: [], compatiblePrintsCondition: '', filamentNotes: '' } const REQUIRED_PROPERTIES = ['name', 'filamentType', 'filament'] const SUMMARY_PROPERTIES = [ ...REQUIRED_PROPERTIES, ...FILAMENT_PROFILE_MATERIAL_PROPERTIES, ...FILAMENT_PROFILE_FLOW_PRESSURE_PROPERTIES, ...FILAMENT_PROFILE_TEMPERATURE_PROPERTIES, ...FILAMENT_PROFILE_BED_TEMPERATURE_PROPERTIES, ...FILAMENT_PROFILE_SPEED_PROPERTIES, ...FILAMENT_PROFILE_COOLING_PROPERTIES, ...FILAMENT_PROFILE_EXHAUST_FAN_PROPERTIES ] const FilamentProfileWizard = ({ objectData, formValid, loading, onSubmit, editing, filamentId = null }) => { const visibleProperties = useMemo(() => { if (!filamentId) return undefined return { filament: false, 'filament._id': false } }, [filamentId]) const steps = useMemo( () => [ { title: 'Required', key: 'required', content: ( ) }, { title: 'Material', key: 'material', content: ( ) }, { title: 'Flow & Pressure', key: 'flowPressure', content: ( ) }, { title: 'Temperature', key: 'temperature', content: ( ) }, { title: 'Speed', key: 'speed', content: ( ) }, { title: 'Cooling', key: 'cooling', content: ( ) }, { title: 'Exhaust Fan', key: 'exhaustFan', content: ( ) }, { title: 'Compatibility', key: 'compatibility', content: ( ) }, { title: 'Summary', key: 'summary', content: ( ) } ], [objectData, visibleProperties] ) return ( ) } FilamentProfileWizard.propTypes = { objectData: PropTypes.object, formValid: PropTypes.bool.isRequired, loading: PropTypes.bool, onSubmit: PropTypes.func.isRequired, editing: PropTypes.bool, filamentId: PropTypes.string } const NewFilamentProfile = ({ onOk, filamentId = null }) => ( {({ handleSubmit, submitLoading, objectData, formValid }) => ( { const result = await handleSubmit() if (result?._id) onOk(result) }} /> )} ) NewFilamentProfile.propTypes = { onOk: PropTypes.func.isRequired, filamentId: PropTypes.string } export const EditFilamentProfile = ({ profileId, onOk, filamentId = null }) => { const formRef = useRef(null) const startedEditingRef = useRef(false) const saveRequestedRef = useRef(false) const stateRef = useRef({}) const [formState, setFormState] = useState({ loading: true, editLoading: false, formValid: false, isEditing: false, objectData: {} }) useEffect(() => { if ( !formState.loading && !formState.isEditing && !startedEditingRef.current ) { startedEditingRef.current = true formRef.current?.startEditing() } }, [formState.isEditing, formState.loading]) return ( { stateRef.current = { ...stateRef.current, ...nextState } setFormState((current) => ({ ...current, ...nextState })) if (saveRequestedRef.current && nextState.isEditing === false) { saveRequestedRef.current = false onOk(stateRef.current.objectData) } }} > {({ objectData, formValid, editLoading, handleUpdate }) => ( { saveRequestedRef.current = true handleUpdate() }} /> )} ) } EditFilamentProfile.propTypes = { profileId: PropTypes.string.isRequired, onOk: PropTypes.func.isRequired, filamentId: PropTypes.string } export default NewFilamentProfile